// Windows/Synchronization.cpp #include "StdAfx.h" #include "Synchronization.h" // #define TRACEN(u) u; #define TRACEN(u) /* */ #define MAGIC 0x1234CAFE class CSynchroTest { int _magic; public: CSynchroTest() { _magic = MAGIC; } void testConstructor() { if (_magic != MAGIC) { printf("ERROR : no constructors called during loading of plugins (please look at LINK_SHARED in makefile.machine)\n"); exit(EXIT_FAILURE); } } }; static CSynchroTest gbl_synchroTest; extern "C" void sync_TestConstructor(void) { gbl_synchroTest.testConstructor(); } namespace NWindows { namespace NSynchronization { #ifndef ENV_BEOS #ifdef DEBUG_SYNCHRO void CSynchro::dump_error(int ligne,int ret,const char *text,void *param) { printf("\n##T%d#ERROR2 (l=%d) %s : param=%p ret = %d (%s)##\n",(int)pthread_self(),ligne,text,param,ret,strerror(ret)); // abort(); } CSynchro::CSynchro() { TRACEN((printf("\nT%d : E1-CSynchro(this=%p,m=%p,cond=%p)\n",(int)pthread_self(),(void *)this,(void *)&_object,(void *)&_cond))) _isValid = false; } void CSynchro::Create() { TRACEN((printf("\nT%d : E1-CSynchro::Create(this=%p,m=%p,cond=%p)\n",(int)pthread_self(),(void *)this,(void *)&_object,(void *)&_cond))) pthread_mutexattr_t mutexattr; memset(&mutexattr,0,sizeof(mutexattr)); int ret = pthread_mutexattr_init(&mutexattr); if (ret != 0) { dump_error(__LINE__,ret,"pthread_mutexattr_init",&mutexattr); } ret = pthread_mutexattr_settype(&mutexattr,PTHREAD_MUTEX_ERRORCHECK); if (ret != 0) dump_error(__LINE__,ret,"pthread_mutexattr_settype",&mutexattr); ret = ::pthread_mutex_init(&_object,&mutexattr); if (ret != 0) dump_error(__LINE__,ret,"pthread_mutex_init",&_object); ret = ::pthread_cond_init(&_cond,0); if (ret != 0) dump_error(__LINE__,ret,"pthread_cond_init",&_cond); TRACEN((printf("\nT%d : E2-CSynchro::Create(m=%p,cond=%p)\n",(int)pthread_self(),(void *)&_object,(void *)&_cond))) } CSynchro::~CSynchro() { TRACEN((printf("\nT%d : E1-~CSynchro(this=%p,m=%p,cond=%p)\n",(int)pthread_self(),(void *)this,(void *)&_object,(void *)&_cond))) if (_isValid) { int ret = ::pthread_mutex_destroy(&_object); if (ret != 0) dump_error(__LINE__,ret,"pthread_mutex_destroy",&_object); ret = ::pthread_cond_destroy(&_cond); if (ret != 0) dump_error(__LINE__,ret,"pthread_cond_destroy",&_cond); TRACEN((printf("\nT%d : E2-~CSynchro(m=%p,cond=%p)\n",(int)pthread_self(),(void *)&_object,(void *)&_cond))) } _isValid = false; } void CSynchro::Enter() { TRACEN((printf("\nT%d : E1-CSynchro::Enter(%p)\n",(int)pthread_self(),(void *)&_object))) int ret = ::pthread_mutex_lock(&_object); if (ret != 0) { dump_error(__LINE__,ret,"CSynchro::Enter-pthread_mutex_lock",&_object); } TRACEN((printf("\nT%d : E2-CSynchro::Enter(%p)\n",(int)pthread_self(),(void *)&_object))) } void CSynchro::Leave() { TRACEN((printf("\nT%d : E1-CSynchro::Leave(%p)\n",(int)pthread_self(),(void *)&_object))) int ret = ::pthread_mutex_unlock(&_object); if (ret != 0) dump_error(__LINE__,ret,"Leave::pthread_mutex_unlock",&_object); TRACEN((printf("\nT%d : E2-CSynchro::Leave(%p)\n",(int)pthread_self(),(void *)&_object))) } void CSynchro::WaitCond() { TRACEN((printf("\nT%d : E1-CSynchro::WaitCond(%p,%p)\n",(int)pthread_self(),(void *)&_cond,(void *)&_object))) int ret = ::pthread_cond_wait(&_cond, &_object); if (ret != 0) dump_error(__LINE__,ret,"pthread_cond_wait",&_cond); TRACEN((printf("\nT%d : E2-CSynchro::WaitCond(%p,%p)\n",(int)pthread_self(),(void *)&_cond,(void *)&_object))) } void CSynchro::LeaveAndSignal() { TRACEN((printf("\nT%d : E1-CSynchro::LeaveAndSignal(%p)\n",(int)pthread_self(),(void *)&_cond))) int ret = ::pthread_cond_broadcast(&_cond); if (ret != 0) dump_error(__LINE__,ret,"pthread_cond_broadcast",&_cond); TRACEN((printf("\nT%d : E2-CSynchro::LeaveAndSignal(%p)\n",(int)pthread_self(),(void *)&_object))) ret = ::pthread_mutex_unlock(&_object); if (ret != 0) dump_error(__LINE__,ret,"LeaveAndSignal::pthread_mutex_unlock",&_object); TRACEN((printf("\nT%d : E3-CSynchro::LeaveAndSignal(%p)\n",(int)pthread_self(),(void *)&_cond))) } #endif #endif }} DWORD WINAPI WaitForMultipleObjects( DWORD count, const HANDLE *handles, BOOL wait_all, DWORD timeout ) { TRACEN((printf("\nT%d : E1-WaitForMultipleObjects(%d)\n",(int)pthread_self(),(int)count))) if (wait_all != FALSE) { printf("\n\n INTERNAL ERROR - WaitForMultipleObjects(...) wait_all(%d) != FALSE\n\n",(unsigned)wait_all); abort(); } if (timeout != INFINITE) { printf("\n\n INTERNAL ERROR - WaitForMultipleObjects(...) timeout(%u) != INFINITE\n\n",(unsigned)timeout); abort(); } if (count < 1) { printf("\n\n INTERNAL ERROR - WaitForMultipleObjects(...) count(%u) < 1\n\n",(unsigned)count); abort(); } NWindows::NSynchronization::CSynchro *synchro = handles[0]->_sync; TRACEN((printf("\nT%d : E2-WaitForMultipleObjects(%d)\n",(int)pthread_self(),(int)count))) synchro->Enter(); TRACEN((printf("\nT%d : E3-WaitForMultipleObjects(%d)\n",(int)pthread_self(),(int)count))) #ifdef DEBUG_SYNCHRO for(DWORD i=1;i_sync) { printf("\n\n INTERNAL ERROR - WaitForMultipleObjects(...) synchro(%p) != handles[%d]->_sync(%p)\n\n", synchro,(unsigned)i,handles[i]->_sync); abort(); } } #endif while(1) { for(DWORD i=0;iIsSignaledAndUpdate()) { synchro->Leave(); TRACEN((printf("\nT%d : E4-WaitForMultipleObjects(%d)\n",(int)pthread_self(),(int)count))) return WAIT_OBJECT_0+i; } } synchro->WaitCond(); } synchro->Leave(); return ETIMEDOUT; // WAIT_TIMEOUT; }