6 #include <VersionHelpers.h>
39Thread::Thread(
const char_t* _name )
51 #define __key_t pthread_key_t
52 #define __key_create(key) pthread_key_create(&key, NULL)
53 #define __key_delete(key) pthread_key_delete(key)
54 #define __key_get(key) pthread_getspecific(key)
55 #define __key_set(key, value) pthread_setspecific(key, value)
56 #define __key_set_success(key, value) pthread_setspecific(key, value) == 0
59 #define __key_create(key) key = TlsAlloc()
60 #define __key_delete(key) TlsFree(key)
61 #define __key_get(key) TlsGetValue(key)
62 #define __key_set(key, value) TlsSetValue(key, value)
63 #define __key_set_success(key, value) TlsSetValue(key, value) == TRUE
66static __key_t __keyCurrentThread = (__key_t) -1;
74 int n = pthread_create(
76 (pthread_attr_t*)
NULL,
77 Thread::startRoutine, (
void*)
this
80 throw new SysError(
n);
83 __hThread = CreateThread(
92 if (__hThread ==
NULL)
93 throw new SysError(GetLastError());
99 return __key_set_success(__keyCurrentThread,
this);
105 return (Thread*) __key_get(__keyCurrentThread);
113Thread::startRoutine(
void* _pThread)
121 catch (Exception* cause) {
127 return (
void*)(size_t)
r;
137 pthread_join(__threadId, &
r);
140 WaitForSingleObject(__hThread,
INFINITE);
141 GetExitCodeThread(__hThread, &
r);
142 CloseHandle(__hThread);
147 return (
int)(size_t)
r;
157 poll(
NULL, 0, _mills);
176 return pthread_self();
178 return GetCurrentThreadId();
182void Thread::once(OnceType& _onceControl, initRoutine _initRoutine)
186 pthread_once(&_onceControl, _initRoutine);
188 if (_onceControl != ONCE_INIT)
199 int failed = pthread_key_create(&rKey,
NULL);
201 throw new SysError(failed);
204 KeyType rKey = TlsAlloc();
205 if (rKey == TLS_OUT_OF_INDEXES)
206 throw new SysError(GetLastError());
214 int failed = pthread_key_delete(_key);
225 int failed = pthread_setspecific(_key, _value);
229 if (!TlsSetValue(_key, _value))
236 return pthread_getspecific(_key);
238 void* p = TlsGetValue(_key);
239 if (p ==
NULL && GetLastError() != ERROR_SUCCESS)
246 #define __lock_t pthread_spinlock_t
247 #define __init(lock) pthread_spin_init(&lock, PTHREAD_PROCESS_PRIVATE)
248 #define __destroy(lock) pthread_spin_destroy(&lock)
249 #define __lock(lock) pthread_spin_lock(&lock)
250 #define __unlock(lock) pthread_spin_unlock(&lock)
252 #define __lock_t CRITICAL_SECTION
253 #define __init(lock) InitializeCriticalSectionAndSpinCount(&lock, INFINITE)
254 #define __destroy(lock) DeleteCriticalSection(&lock)
255 #define __lock(lock) EnterCriticalSection(&lock)
256 #define __unlock(lock) LeaveCriticalSection(&lock)
259#define __LOCK_COUNT 7
294#if __DCL_WINDOWS && _WIN32_WINNT < 0x0600
300 long long n = ++(_n);
309 long long n = --(_n);
318 __key_create(__keyCurrentThread);
326 __key_delete(__keyCurrentThread);
329 __destroy(__lock[i]);
332Thread::Event::Event()
348Thread::Event::~Event()
358void Thread::Event::set()
362 __DCL_VERIFY(write(__fds[1], &c,
sizeof(c)) ==
sizeof(c));
368void Thread::Event::reset()
372 ioctl(__fds[READ_FD_INDEX], FIONREAD, &nbytes);
375 int n = read(__fds[0],
buf, nbytes < 100 ? nbytes : 100);
388bool Thread::Event::wait(
unsigned int _milliseconds)
394 pfd.fd = __fds[READ_FD_INDEX];
398 int n = poll(&pfd, 1, _milliseconds);
405 switch(WaitForSingleObject(__hEvent, _milliseconds)) {
410 SetLastError(ERROR_TIMEOUT);
425 InitializeCriticalSectionAndSpinCount(&__cs, _dwSpinCount);
434 InitializeCriticalSection(&__cs);
443 DeleteCriticalSection(&__cs);
452 EnterCriticalSection(&__cs);
459 int r = pthread_mutex_trylock(&__mutex);
465 return TryEnterCriticalSection(&__cs) ==
TRUE;
474 LeaveCriticalSection(&__cs);
479Thread::SpinLock::SpinLock(
bool _pshared )
482 _pshared ? PTHREAD_PROCESS_SHARED : PTHREAD_PROCESS_PRIVATE
486Thread::SpinLock::~SpinLock()
491void Thread::SpinLock::lock()
496bool Thread::SpinLock::tryLock()
498 int r = pthread_spin_trylock(&__spinLock);
505void Thread::SpinLock::unlock()
511#if __DCL_PTHREAD || (__DCL_WINDOWS && _WIN32_WINNT >= 0x0600)
512Thread::ReadWriteLock::ReadWriteLock()
517 InitializeSRWLock(&__srwlock);
521Thread::ReadWriteLock::~ReadWriteLock()
528void Thread::ReadWriteLock::readLock()
533 AcquireSRWLockShared(&__srwlock);
537void Thread::ReadWriteLock::writeLock()
542 AcquireSRWLockExclusive(&__srwlock);
547bool Thread::ReadWriteLock::tryReadLock()
549 int r = pthread_rwlock_tryrdlock(&__rwlock);
555bool Thread::ReadWriteLock::tryWriteLock()
557 int r = pthread_rwlock_trywrlock(&__rwlock);
563void Thread::ReadWriteLock::unlock()
568void Thread::ReadWriteLock::readUnlock()
570 ReleaseSRWLockShared(&__srwlock);
572void Thread::ReadWriteLock::writeUnlock()
574 ReleaseSRWLockExclusive(&__srwlock);
584#elif __DCL_WINDOWS && _WIN32_WINNT >= 0x0600
587 InitializeConditionVariable(&__cond);
604 #if _WIN32_WINNT >= 0x0600
605 WakeConditionVariable(&__cond);
612#if __DCL_PTHREAD || (__DCL_WINDOWS && _WIN32_WINNT >= 0x0600)
613void Thread::CondVar::broadcast()
618 WakeAllConditionVariable(&__cond);
629 if (_milliseconds == (
unsigned int)
INFINITE) {
630 __DCL_VERIFY(pthread_cond_wait(&__cond, (pthread_mutex_t*)&_mutex) == 0);
641 ts.tv_sec = tv.tv_sec + (_milliseconds / 1000);
642 ts.tv_nsec = (tv.tv_usec * 1000) + ((_milliseconds % 1000) * 1000000);
643 int n = pthread_cond_timedwait(&__cond, (pthread_mutex_t*)&_mutex, &ts);
652 #if _WIN32_WINNT >= 0x0600
653 if (!SleepConditionVariableCS(&__cond,
654 (CRITICAL_SECTION*)&_mutex, _milliseconds)) {
671#if __DCL_WINDOWS && _WIN32_WINNT >= 0x0600
676 if (!SleepConditionVariableSRW(&__cond, (SRWLOCK *)&_lock,
677 _shared ? CONDITION_VARIABLE_LOCKMODE_SHARED : 0, _milliseconds)) {
687Thread::Barrier::Barrier(
unsigned int _count)
692Thread::Barrier::~Barrier()
697void Thread::Barrier::wait()
#define __DCL_ASSERT_PARAM(expr)
#define __DCL_VERIFY(expr)
#define __DCL_ASSERT(expr)
#define IMPLEMENT_CLASSINFO(class_name, base_class_name)
#define __DCL_TRACE2(fmt, arg1, arg2)
void CharsetConvertException *size_t n
void __cleanupThreadEnvironment()
void __initializeThreadEnvironment()
String toStringAll() const
virtual String toString() const
bool wait(Mutex &_mutex, unsigned int _milliseconds=INFINITE)
static void crtLock(const void *_p)
static long incrementAndGet(volatile long &_n)
static void crtUnlock(const void *_p)
static void sleep(unsigned int _mills)
static unsigned long getCurrentThreadId()
static Thread * getCurrentThread()
static long decrementAndGet(volatile long &_n)