1 /* 2 * Part of WCM Commander 3 * https://github.com/corporateshark/WCMCommander 4 * wcm@linderdaum.com 5 */ 6 7 #pragma once 8 9 #include "swl.h" 10 11 using namespace wal; 12 13 14 typedef int ( * volatile OperCallback )( void* cbData ); 15 16 class OperThreadWin; 17 18 class OperThreadNode 19 { 20 friend class OperThreadWin; 21 friend void* __123___OperThread( void* ); 22 23 OperThreadWin* volatile win; 24 25 std::string threadInfo; //++volatile !!! 26 OperThreadNode* volatile prev; 27 OperThreadNode* volatile next; 28 volatile bool stopped; 29 Mutex mutex; 30 void* volatile data; 31 32 void* volatile cbData; 33 Cond cbCond; 34 volatile int cbRet; 35 OperCallback cbFunc; 36 public: OperThreadNode(OperThreadWin * w,const char * info,void * d)37 OperThreadNode( OperThreadWin* w, const char* info, void* d ) 38 : win( w ), threadInfo( info ), prev( 0 ), next( 0 ), 39 stopped( false ), data( d ), 40 cbData( 0 ), cbRet( -1 ), cbFunc( 0 ) 41 {} 42 GetMutex()43 Mutex* GetMutex() { return &mutex; } 44 Data()45 void* Data() { return data; } //можно вызывать и работать с данными только заблакировав mutex получаемый через GetMutex NBStopped()46 bool NBStopped() { return stopped; } //можно вызывать только заблакировав mutex получаемый через GetMutex 47 48 int CallBack( OperCallback f, void* data ); // ret < 0 if stopped 49 50 //!!! id >= 2 SendSignal(int id)51 bool SendSignal( int id ) //обязательно запускать при НЕзалоченном mutex 52 { MutexLock lock( &mutex ); if ( stopped || id <= 1 ) { return false; } return WinThreadSignal( id ); } 53 54 ~OperThreadNode(); 55 private: OperThreadNode()56 OperThreadNode() {} 57 CLASS_COPY_PROTECTION( OperThreadNode ); 58 }; 59 60 //ф-ция потока, не должна пропускать исключений 61 //поток может посылать сигналы только через tData 62 typedef void ( *OperThreadFunc )( OperThreadNode* node ); 63 64 65 class OperThreadWin: public Win 66 { 67 friend void* __123___OperThread( void* ); 68 int nextThreadId; NewThreadID()69 int NewThreadID() { int n = nextThreadId; nextThreadId = ( ( nextThreadId + 1 ) % 0x10000 ); return n + 1; } 70 71 int threadId; 72 OperThreadNode* tNode; 73 bool cbExecuted; 74 public: 75 OperThreadWin( WTYPE t, unsigned hints = 0, int nId = 0, Win* _parent = nullptr, const crect* rect = nullptr ) Win(t,hints,_parent,rect,nId)76 : Win( t, hints, _parent, rect, nId ), nextThreadId( 0 ), tNode( 0 ), cbExecuted( false ) {} 77 78 void RunNewThread( const char* info, OperThreadFunc f, void* data ); //может быть исключение 79 virtual void OperThreadSignal( int info ); 80 virtual void OperThreadStopped(); 81 82 void StopThread(); 83 void SetStopFlag(); 84 85 static void DBGPrintStoppingList(); 86 87 virtual void ThreadSignal( int id, int data ); 88 virtual void ThreadStopped( int id, void* data ); 89 virtual ~OperThreadWin(); 90 }; 91