2 // lots of code here is (c) Bartosz Milewski, 1996, www.relisoft.com
3 // The rest is (C) 2002-2004 Royce Mitchell III
4 // and released under the LGPL & BSD licenses
9 # define WIN32_LEAN_AND_MEAN
11 # define snprintf _snprintf
16 # error unrecognized target
21 ////////////////////////////////////////////////////////////////////////////////
24 void _wassert ( char* szExpr
, char* szFile
, int line
)
26 fprintf ( stderr
, "Assertion Failure: \"%s\" in file %s, line %d", szExpr
, szFile
, line
);
31 ////////////////////////////////////////////////////////////////////////////////
34 Thread::Thread ( long (THREADAPI
* pFun
) (void* arg
), void* pArg
)
37 verify ( _handle
= CreateThread (
38 0, // Security attributes
40 (DWORD (WINAPI
*)(void*))pFun
,
42 0, // don't create suspended.
45 // set up the thread attribute: right now, we do nothing with it.
47 pthread_attr_init(&attr
);
49 // this will make the threads created by this process really concurrent
50 verify ( !pthread_attr_setscope(&attr
, PTHREAD_SCOPE_SYSTEM
) );
52 // create the new OS thread object
53 verify ( !pthread_create ( &_threadId
, &attr
, (void* (*) (void*))pFun
, pArg
) );
55 verify ( !pthread_attr_destroy(&attr
) );
57 # error unrecognized target
64 verify ( CloseHandle ( _handle
) );
66 verify ( !pthread_cancel ( _threadId
) );
68 # error unrecognized target
72 /*void Thread::Resume()
75 ResumeThread (_handle);
77 # error how to resume thread in unix?
79 # error unrecognized target
83 void Thread::WaitForDeath()
86 DWORD dw
= WaitForSingleObject ( _handle
, 2000 );
87 ASSERT ( dw
!= WAIT_FAILED
);
89 verify ( !pthread_join ( _threadId
, (void**)NULL
) );
91 # error unrecognized target
96 ////////////////////////////////////////////////////////////////////////////////
99 // The constructor of the derived class
102 // at the end of construction
104 ActiveObject::ActiveObject() : _isDying (0), _thread (0)
108 ActiveObject::~ActiveObject()
110 ASSERT ( !_thread
); // call Kill() from subclass's dtor
111 // Kill() - // You can't call a virtual function from a dtor, EVEN INDIRECTLY
112 // so, you must call Kill() in the subclass's dtor
115 // FlushThread must reset all the events on which the thread might be waiting.
116 void ActiveObject::Kill()
122 // Let's make sure it's gone
123 _thread
->WaitForDeath();
129 void ActiveObject::Start()
132 _thread
= new Thread ( ThreadEntry
, this );
135 long THREADAPI
ActiveObject::ThreadEntry ( void* pArg
)
137 ActiveObject
* pActive
= (ActiveObject
*)pArg
;
138 pActive
->InitThread();
145 ///////////////////////////////////////////////////////////////////////////////
151 verify ( _h
= CreateMutex ( NULL
, FALSE
, NULL
) );
153 pthread_mutexattr_t attrib
;
154 verify ( !pthread_mutexattr_init( &attrib
) );
155 // allow recursive locks
156 verify ( !pthread_mutexattr_settype( &attrib
, PTHREAD_MUTEX_RECURSIVE
) );
157 verify ( !pthread_mutex_init ( &_mutex
, &attrib
) );
159 # error unrecognized target
166 verify ( CloseHandle ( _h
) );
168 verify ( !pthread_mutex_destroy(&_mutex
) );
170 # error unrecognized target
174 void Mutex::Acquire()
177 DWORD dw
= WaitForSingleObject ( _h
, INFINITE
);
178 ASSERT ( dw
== WAIT_OBJECT_0
|| dw
== WAIT_ABANDONED
);
180 verify ( !pthread_mutex_lock(&_mutex
) );
182 # error unrecognized target
186 bool Mutex::TryAcquire()
189 DWORD dw
= WaitForSingleObject ( _h
, 1 );
190 ASSERT ( dw
== WAIT_OBJECT_0
|| dw
== WAIT_TIMEOUT
|| dw
== WAIT_ABANDONED
);
191 return (dw
!= WAIT_TIMEOUT
);
193 int err
= pthread_mutex_trylock(&_mutex
);
194 ASSERT ( err
== EBUSY
|| err
== 0 );
197 # error unrecognized target
201 void Mutex::Release()
204 verify ( ReleaseMutex ( _h
) );
206 verify ( !pthread_mutex_unlock(&_mutex
) );
207 // we could allow EPERM return value too, but we are forcing user into RIIA
209 # error unrecognized target
213 Mutex::Lock::Lock ( Mutex
& m
) : _m(m
)
223 Mutex::TryLock::TryLock ( Mutex
& m
) : _m(m
)
225 _bLocked
= _m
.TryAcquire();
228 Mutex::TryLock::~TryLock()
234 ///////////////////////////////////////////////////////////////////////////////
240 // start in non-signaled state (red light)
241 // auto reset after every Wait
242 verify ( _handle
= CreateEvent ( 0, FALSE
, FALSE
, 0 ) );
244 //verify ( !pthread_cond_init ( &_cond, NULL /* default attributes */) );
246 //verify(sem_init());
248 # error unrecognized target
255 verify ( CloseHandle ( _handle
) );
257 //verify ( !pthread_cond_destroy ( &_cond ) );
260 # error unrecognized target
264 void Event::Release() // put into signaled state
267 verify ( SetEvent ( _handle
) );
269 //verify ( !pthread_cond_signal ( &_cond ) );
272 # error unrecognized target
279 // Wait until event is in signaled (green) state
280 DWORD dw
= WaitForSingleObject ( _handle
, INFINITE
);
281 ASSERT ( dw
== WAIT_OBJECT_0
|| dw
== WAIT_ABANDONED
);
283 // According to docs: The pthread_cond_wait() and pthread_cond_timedwait()
284 // functions are used to block on a condition variable. They are called
285 // with mutex locked by the calling thread or undefined behaviour will
287 //Mutex::Lock lock ( _mutex );
288 //verify ( !pthread_cond_wait ( &_cond, _mutex ) );
291 # error unrecognized target
296 void Event::sem_init()
298 sem_id
= semget(IPC_PRIVATE
, 1, 0666 | IPC_CREAT
);
299 ASSERT(sem_id
!= -1);
308 return semop(sem_id
, &sb
, 1);
317 return semop(sem_id
, &sb
, 1);
320 void Event::sem_destroy()
325 semctl(sem_id
, 0, IPC_RMID
, mactmp
);
327 semctl(sem_id
, 0, IPC_RMID
, 0);