/* * Part of WCM Commander * https://github.com/corporateshark/WCMCommander * wcm@linderdaum.com */ #pragma once #include "swl.h" using namespace wal; typedef int ( * volatile OperCallback )( void* cbData ); class OperThreadWin; class OperThreadNode { friend class OperThreadWin; friend void* __123___OperThread( void* ); OperThreadWin* volatile win; std::string threadInfo; //++volatile !!! OperThreadNode* volatile prev; OperThreadNode* volatile next; volatile bool stopped; Mutex mutex; void* volatile data; void* volatile cbData; Cond cbCond; volatile int cbRet; OperCallback cbFunc; public: OperThreadNode( OperThreadWin* w, const char* info, void* d ) : win( w ), threadInfo( info ), prev( 0 ), next( 0 ), stopped( false ), data( d ), cbData( 0 ), cbRet( -1 ), cbFunc( 0 ) {} Mutex* GetMutex() { return &mutex; } void* Data() { return data; } //можно вызывать и работать с данными только заблакировав mutex получаемый через GetMutex bool NBStopped() { return stopped; } //можно вызывать только заблакировав mutex получаемый через GetMutex int CallBack( OperCallback f, void* data ); // ret < 0 if stopped //!!! id >= 2 bool SendSignal( int id ) //обязательно запускать при НЕзалоченном mutex { MutexLock lock( &mutex ); if ( stopped || id <= 1 ) { return false; } return WinThreadSignal( id ); } ~OperThreadNode(); private: OperThreadNode() {} CLASS_COPY_PROTECTION( OperThreadNode ); }; //ф-ция потока, не должна пропускать исключений //поток может посылать сигналы только через tData typedef void ( *OperThreadFunc )( OperThreadNode* node ); class OperThreadWin: public Win { friend void* __123___OperThread( void* ); int nextThreadId; int NewThreadID() { int n = nextThreadId; nextThreadId = ( ( nextThreadId + 1 ) % 0x10000 ); return n + 1; } int threadId; OperThreadNode* tNode; bool cbExecuted; public: OperThreadWin( WTYPE t, unsigned hints = 0, int nId = 0, Win* _parent = nullptr, const crect* rect = nullptr ) : Win( t, hints, _parent, rect, nId ), nextThreadId( 0 ), tNode( 0 ), cbExecuted( false ) {} void RunNewThread( const char* info, OperThreadFunc f, void* data ); //может быть исключение virtual void OperThreadSignal( int info ); virtual void OperThreadStopped(); void StopThread(); void SetStopFlag(); static void DBGPrintStoppingList(); virtual void ThreadSignal( int id, int data ); virtual void ThreadStopped( int id, void* data ); virtual ~OperThreadWin(); };