* thread.h (class List): Move inline code inside class

declaration.
(List::forEach): Change callback parameter to template class
member functionpointer.
(pthread_keys::fixup_before_fork): Change to inline. Use
List::forEach to fixup keys.
(pthread_keys::fixup_after_fork): Ditto.
(pthread_keys::runAllDestructors): Ditto.
(pthread_key::saveAKey): Remove.
(pthread_key::restoreAKey): Ditto.
(pthread_key::destroyAKey): Ditto.
(pthread_key::run_destructor): Rename to runDestructor.
(pthread_mutex::fixup_after_fork): Change to inline. Use
List::forEach to fixup mutexes after a fork.
(pthread_mutex::FixupAfterFork): New method.
(pthread_mutex::mutexes): New member.
(pthread_cond::fixup_after_fork): Change to inline. Use
List::forEach to fixup conds after a fork.
(pthread_cond::FixupAfterFork): New method.
(pthread_cond::conds): New member.
(pthread_rwlock::fixup_after_fork): Change to inline. Use
List::forEach to fixup rwlocks after a fork.
(pthread_rwlock::FixupAfterFork): New method.
(pthread_rwlock::rwlocks): New member.
(semaphore::fixup_after_fork): Change to inline. Use
List::forEach to fixup mutexes after a fork.
(semaphore::FixupAfterFork): New method.
(semaphore::semaphores): New member.
(MTinterface::mutexs): Remove.
(MTinterface::conds): Ditto.
(MTinterface::rwlocks): Ditto.
(MTinterface::semaphores): Ditto.
(pthread_equal): Add extern "C".
(pthread_mutex_lock): Ditto.

* thread.cc (MTinterface::fixup_after_fork): Change
fixup_after_fork calls for pthread objects.
(semaphore::conds): Instantiate.
(pthread_cond::pthread_cond): Use List::Insert rather than
custom list code.
(pthread_cond::~pthread_cond): Use List::Remove rather than
custom list code.
(pthread_cond::fixup_after_fork): Rename to FixupAfterFork.
(pthread_rwlock::rwlocks): Instantiate.
(pthread_rwlock::pthread_crwlock): Use List::Insert rather than
custom list code.
(pthread_rwlock::~pthread_rwlock): Use List::Remove rather than
custom list code.
(pthread_rwlock::fixup_after_fork): Rename to FixupAfterFork.
(pthread_key::saveAKey): Remove.
(pthread_key::fixup_before_fork): Ditto.
(pthread_key::restoreAKey): Ditto.
(pthread_key::fixup_after_fork): Ditto.
(pthread_key::destroyAKey): Ditto.
(pthread_key::runAllDestructors): Ditto.
(pthread_key::run_destructor): Rename to runDestructor.
(pthread_mutex::mutexes): Instantiate.
(pthread_mutex::pthread_mutex): Use List::Insert rather than
custom list code.
(pthread_mutex::~pthread_mutex): Use List::Remove rather than
custom list code.
(pthread_mutex::fixup_after_fork): Rename to FixupAfterFork.
(semaphore::conds): Instantiate.
(semaphore::semaphore): Use List::Insert rather than custom list
code.
(semaphores::~semaphore): Use List::Remove rather than custom
list code.
(semaphore::fixup_after_fork): Rename to FixupAfterFork.
This commit is contained in:
Thomas Pfaff 2003-03-23 10:52:02 +00:00
parent 522fcf1615
commit 9306ba2ee4
3 changed files with 201 additions and 209 deletions

View File

@ -1,3 +1,74 @@
2003-03-23 Thomas Pfaff <tpfaff@gmx.net>
* thread.h (class List): Move inline code inside class
declaration.
(List::forEach): Change callback parameter to template class
member function pointer.
(pthread_keys::fixup_before_fork): Change to inline. Use
List::forEach to fixup keys.
(pthread_keys::fixup_after_fork): Ditto.
(pthread_keys::runAllDestructors): Ditto.
(pthread_key::saveAKey): Remove.
(pthread_key::restoreAKey): Ditto.
(pthread_key::destroyAKey): Ditto.
(pthread_key::run_destructor): Rename to runDestructor.
(pthread_mutex::fixup_after_fork): Change to inline. Use
List::forEach to fixup mutexes after a fork.
(pthread_mutex::FixupAfterFork): New method.
(pthread_mutex::mutexes): New member.
(pthread_cond::fixup_after_fork): Change to inline. Use
List::forEach to fixup conds after a fork.
(pthread_cond::FixupAfterFork): New method.
(pthread_cond::conds): New member.
(pthread_rwlock::fixup_after_fork): Change to inline. Use
List::forEach to fixup rwlocks after a fork.
(pthread_rwlock::FixupAfterFork): New method.
(pthread_rwlock::rwlocks): New member.
(semaphore::fixup_after_fork): Change to inline. Use
List::forEach to fixup mutexes after a fork.
(semaphore::FixupAfterFork): New method.
(semaphore::semaphores): New member.
(MTinterface::mutexs): Remove.
(MTinterface::conds): Ditto.
(MTinterface::rwlocks): Ditto.
(MTinterface::semaphores): Ditto.
(pthread_equal): Add extern "C".
(pthread_mutex_lock): Ditto.
* thread.cc (MTinterface::fixup_after_fork): Change
fixup_after_fork calls for pthread objects.
(semaphore::conds): Instantiate.
(pthread_cond::pthread_cond): Use List::Insert rather than
custom list code.
(pthread_cond::~pthread_cond): Use List::Remove rather than
custom list code.
(pthread_cond::fixup_after_fork): Rename to FixupAfterFork.
(pthread_rwlock::rwlocks): Instantiate.
(pthread_rwlock::pthread_crwlock): Use List::Insert rather than
custom list code.
(pthread_rwlock::~pthread_rwlock): Use List::Remove rather than
custom list code.
(pthread_rwlock::fixup_after_fork): Rename to FixupAfterFork.
(pthread_key::saveAKey): Remove.
(pthread_key::fixup_before_fork): Ditto.
(pthread_key::restoreAKey): Ditto.
(pthread_key::fixup_after_fork): Ditto.
(pthread_key::destroyAKey): Ditto.
(pthread_key::runAllDestructors): Ditto.
(pthread_key::run_destructor): Rename to runDestructor.
(pthread_mutex::mutexes): Instantiate.
(pthread_mutex::pthread_mutex): Use List::Insert rather than
custom list code.
(pthread_mutex::~pthread_mutex): Use List::Remove rather than
custom list code.
(pthread_mutex::fixup_after_fork): Rename to FixupAfterFork.
(semaphore::conds): Instantiate.
(semaphore::semaphore): Use List::Insert rather than custom list
code.
(semaphores::~semaphore): Use List::Remove rather than custom
list code.
(semaphore::fixup_after_fork): Rename to FixupAfterFork.
2003-03-22 Christopher Faylor <cgf@redhat.com> 2003-03-22 Christopher Faylor <cgf@redhat.com>
* pipe.cc (fhandler_pipe::dup): Don't dup input_handle if it doesn't * pipe.cc (fhandler_pipe::dup): Don't dup input_handle if it doesn't

View File

@ -217,34 +217,10 @@ MTinterface::fixup_after_fork (void)
threadcount = 1; threadcount = 1;
pthread::initMainThread (true); pthread::initMainThread (true);
pthread_mutex *mutex = mutexs; pthread_mutex::fixup_after_fork ();
debug_printf ("mutexs is %x",mutexs); pthread_cond::fixup_after_fork ();
while (mutex) pthread_rwlock::fixup_after_fork ();
{ semaphore::fixup_after_fork ();
mutex->fixup_after_fork ();
mutex = mutex->next;
}
pthread_cond *cond = conds;
debug_printf ("conds is %x",conds);
while (cond)
{
cond->fixup_after_fork ();
cond = cond->next;
}
pthread_rwlock *rwlock = rwlocks;
debug_printf ("rwlocks is %x",rwlocks);
while (rwlock)
{
rwlock->fixup_after_fork ();
rwlock = rwlock->next;
}
semaphore *sem = semaphores;
debug_printf ("semaphores is %x",semaphores);
while (sem)
{
sem->fixup_after_fork ();
sem = sem->next;
}
} }
/* pthread calls */ /* pthread calls */
@ -807,6 +783,8 @@ pthread_condattr::~pthread_condattr ()
{ {
} }
List<pthread_cond> pthread_cond::conds;
/* This is used for cond creation protection within a single process only */ /* This is used for cond creation protection within a single process only */
nativeMutex NO_COPY pthread_cond::condInitializationLock; nativeMutex NO_COPY pthread_cond::condInitializationLock;
@ -862,8 +840,7 @@ pthread_cond::pthread_cond (pthread_condattr *attr) :
return; return;
} }
/* threadsafe addition is easy */ conds.Insert (this);
next = (pthread_cond *) InterlockedExchangePointer (&MT_INTERFACE->conds, this);
} }
pthread_cond::~pthread_cond () pthread_cond::~pthread_cond ()
@ -871,17 +848,7 @@ pthread_cond::~pthread_cond ()
if (semWait) if (semWait)
CloseHandle (semWait); CloseHandle (semWait);
/* I'm not 100% sure the next bit is threadsafe. I think it is... */ conds.Remove (this);
if (MT_INTERFACE->conds == this)
InterlockedExchangePointer (&MT_INTERFACE->conds, this->next);
else
{
pthread_cond *tempcond = MT_INTERFACE->conds;
while (tempcond->next && tempcond->next != this)
tempcond = tempcond->next;
/* but there may be a race between the loop above and this statement */
InterlockedExchangePointer (&tempcond->next, this->next);
}
} }
void void
@ -992,7 +959,7 @@ pthread_cond::Wait (pthread_mutex_t mutex, DWORD dwMilliseconds)
} }
void void
pthread_cond::fixup_after_fork () pthread_cond::FixupAfterFork ()
{ {
waiting = pending = 0; waiting = pending = 0;
mtxCond = NULL; mtxCond = NULL;
@ -1003,7 +970,7 @@ pthread_cond::fixup_after_fork ()
semWait = ::CreateSemaphore (&sec_none_nih, 0, LONG_MAX, NULL); semWait = ::CreateSemaphore (&sec_none_nih, 0, LONG_MAX, NULL);
if (!semWait) if (!semWait)
api_fatal ("pthread_cond::fixup_after_fork () failed to recreate win32 semaphore"); api_fatal ("pthread_cond::FixupAfterFork () failed to recreate win32 semaphore");
} }
bool bool
@ -1023,6 +990,8 @@ pthread_rwlockattr::~pthread_rwlockattr ()
{ {
} }
List<pthread_rwlock> pthread_rwlock::rwlocks;
/* This is used for rwlock creation protection within a single process only */ /* This is used for rwlock creation protection within a single process only */
nativeMutex NO_COPY pthread_rwlock::rwlockInitializationLock; nativeMutex NO_COPY pthread_rwlock::rwlockInitializationLock;
@ -1078,23 +1047,12 @@ pthread_rwlock::pthread_rwlock (pthread_rwlockattr *attr) :
} }
/* threadsafe addition is easy */ rwlocks.Insert (this);
next = (pthread_rwlock *) InterlockedExchangePointer (&MT_INTERFACE->rwlocks, this);
} }
pthread_rwlock::~pthread_rwlock () pthread_rwlock::~pthread_rwlock ()
{ {
/* I'm not 100% sure the next bit is threadsafe. I think it is... */ rwlocks.Remove (this);
if (MT_INTERFACE->rwlocks == this)
InterlockedExchangePointer (&MT_INTERFACE->rwlocks, this->next);
else
{
pthread_rwlock *temprwlock = MT_INTERFACE->rwlocks;
while (temprwlock->next && temprwlock->next != this)
temprwlock = temprwlock->next;
/* but there may be a race between the loop above and this statement */
InterlockedExchangePointer (&temprwlock->next, this->next);
}
} }
int int
@ -1315,7 +1273,7 @@ pthread_rwlock::WrLockCleanup (void *arg)
} }
void void
pthread_rwlock::fixup_after_fork () pthread_rwlock::FixupAfterFork ()
{ {
pthread_t self = pthread::self (); pthread_t self = pthread::self ();
struct RWLOCK_READER **temp = &readers; struct RWLOCK_READER **temp = &readers;
@ -1346,42 +1304,6 @@ pthread_rwlock::fixup_after_fork ()
/* This stores pthread_key information across fork() boundaries */ /* This stores pthread_key information across fork() boundaries */
List<pthread_key> pthread_key::keys; List<pthread_key> pthread_key::keys;
void
pthread_key::saveAKey (pthread_key *key)
{
key->saveKeyToBuffer ();
}
void
pthread_key::fixup_before_fork ()
{
keys.forEach (saveAKey);
}
void
pthread_key::restoreAKey (pthread_key *key)
{
key->recreateKeyFromBuffer ();
}
void
pthread_key::fixup_after_fork ()
{
keys.forEach (restoreAKey);
}
void
pthread_key::destroyAKey (pthread_key *key)
{
key->run_destructor ();
}
void
pthread_key::runAllDestructors ()
{
keys.forEach (destroyAKey);
}
bool bool
pthread_key::isGoodObject (pthread_key_t const *key) pthread_key::isGoodObject (pthread_key_t const *key)
{ {
@ -1445,7 +1367,7 @@ pthread_key::recreateKeyFromBuffer ()
} }
void void
pthread_key::run_destructor () pthread_key::runDestructor ()
{ {
if (destructor) if (destructor)
{ {
@ -1528,6 +1450,8 @@ pthread_mutex::canBeUnlocked (pthread_mutex_t const *mutex)
return (pthread_equal ((*mutex)->owner, self)) && 1 == (*mutex)->recursion_counter; return (pthread_equal ((*mutex)->owner, self)) && 1 == (*mutex)->recursion_counter;
} }
List<pthread_mutex> pthread_mutex::mutexes;
/* This is used for mutex creation protection within a single process only */ /* This is used for mutex creation protection within a single process only */
nativeMutex NO_COPY pthread_mutex::mutexInitializationLock; nativeMutex NO_COPY pthread_mutex::mutexInitializationLock;
@ -1567,8 +1491,7 @@ pthread_mutex::pthread_mutex (pthread_mutexattr *attr) :
type = attr->mutextype; type = attr->mutextype;
} }
/* threadsafe addition is easy */ mutexes.Insert (this);
next = (pthread_mutex *) InterlockedExchangePointer (&MT_INTERFACE->mutexs, this);
} }
pthread_mutex::~pthread_mutex () pthread_mutex::~pthread_mutex ()
@ -1576,19 +1499,7 @@ pthread_mutex::~pthread_mutex ()
if (win32_obj_id) if (win32_obj_id)
CloseHandle (win32_obj_id); CloseHandle (win32_obj_id);
/* I'm not 100% sure the next bit is threadsafe. I think it is... */ mutexes.Remove (this);
if (MT_INTERFACE->mutexs == this)
/* TODO: printf an error if the return value != this */
InterlockedExchangePointer (&MT_INTERFACE->mutexs, next);
else
{
pthread_mutex *tempmutex = MT_INTERFACE->mutexs;
while (tempmutex->next && tempmutex->next != this)
tempmutex = tempmutex->next;
/* but there may be a race between the loop above and this statement */
/* TODO: printf an error if the return value != this */
InterlockedExchangePointer (&tempmutex->next, this->next);
}
} }
int int
@ -1665,11 +1576,11 @@ pthread_mutex::_Destroy (pthread_t self)
} }
void void
pthread_mutex::fixup_after_fork () pthread_mutex::FixupAfterFork ()
{ {
debug_printf ("mutex %x in fixup_after_fork", this); debug_printf ("mutex %x in FixupAfterFork", this);
if (pshared != PTHREAD_PROCESS_PRIVATE) if (pshared != PTHREAD_PROCESS_PRIVATE)
api_fatal ("pthread_mutex::fixup_after_fork () doesn'tunderstand PROCESS_SHARED mutex's"); api_fatal ("pthread_mutex::FixupAfterFork () doesn'tunderstand PROCESS_SHARED mutex's");
if (NULL == owner) if (NULL == owner)
/* mutex has no owner, reset to initial */ /* mutex has no owner, reset to initial */
@ -1680,7 +1591,7 @@ pthread_mutex::fixup_after_fork ()
win32_obj_id = ::CreateSemaphore (&sec_none_nih, 0, LONG_MAX, NULL); win32_obj_id = ::CreateSemaphore (&sec_none_nih, 0, LONG_MAX, NULL);
if (!win32_obj_id) if (!win32_obj_id)
api_fatal ("pthread_mutex::fixup_after_fork () failed to recreate win32 semaphore for mutex"); api_fatal ("pthread_mutex::FixupAfterFork () failed to recreate win32 semaphore for mutex");
condwaits = 0; condwaits = 0;
} }
@ -1702,6 +1613,8 @@ pthread_mutexattr::~pthread_mutexattr ()
{ {
} }
List<semaphore> semaphore::semaphores;
semaphore::semaphore (int pshared, unsigned int value):verifyable_object (SEM_MAGIC) semaphore::semaphore (int pshared, unsigned int value):verifyable_object (SEM_MAGIC)
{ {
this->win32_obj_id = ::CreateSemaphore (&sec_none_nih, value, LONG_MAX, this->win32_obj_id = ::CreateSemaphore (&sec_none_nih, value, LONG_MAX,
@ -1710,25 +1623,16 @@ semaphore::semaphore (int pshared, unsigned int value):verifyable_object (SEM_MA
magic = 0; magic = 0;
this->shared = pshared; this->shared = pshared;
currentvalue = value; currentvalue = value;
/* threadsafe addition is easy */
next = (semaphore *) InterlockedExchangePointer (&MT_INTERFACE->semaphores, this); semaphores.Insert (this);
} }
semaphore::~semaphore () semaphore::~semaphore ()
{ {
if (win32_obj_id) if (win32_obj_id)
CloseHandle (win32_obj_id); CloseHandle (win32_obj_id);
/* I'm not 100% sure the next bit is threadsafe. I think it is... */
if (MT_INTERFACE->semaphores == this) semaphores.Remove (this);
InterlockedExchangePointer (&MT_INTERFACE->semaphores, this->next);
else
{
semaphore *tempsem = MT_INTERFACE->semaphores;
while (tempsem->next && tempsem->next != this)
tempsem = tempsem->next;
/* but there may be a race between the loop above and this statement */
InterlockedExchangePointer (&tempsem->next, this->next);
}
} }
void void
@ -1769,9 +1673,9 @@ semaphore::Wait ()
} }
void void
semaphore::fixup_after_fork () semaphore::FixupAfterFork ()
{ {
debug_printf ("sem %x in fixup_after_fork", this); debug_printf ("sem %x in FixupAfterFork", this);
if (shared != PTHREAD_PROCESS_PRIVATE) if (shared != PTHREAD_PROCESS_PRIVATE)
api_fatal ("doesn't understand PROCESS_SHARED semaphores variables"); api_fatal ("doesn't understand PROCESS_SHARED semaphores variables");
/* FIXME: duplicate code here and in the constructor. */ /* FIXME: duplicate code here and in the constructor. */
@ -2859,7 +2763,7 @@ pthread_sigmask (int operation, const sigset_t *set, sigset_t *old_set)
/* ID */ /* ID */
int extern "C" int
pthread_equal (pthread_t t1, pthread_t t2) pthread_equal (pthread_t t1, pthread_t t2)
{ {
return t1 == t2; return t1 == t2;
@ -2921,7 +2825,7 @@ pthread_mutex_getprioceiling (const pthread_mutex_t *mutex,
return ENOSYS; return ENOSYS;
} }
int extern "C" int
pthread_mutex_lock (pthread_mutex_t *mutex) pthread_mutex_lock (pthread_mutex_t *mutex)
{ {
pthread_mutex_t *themutex = mutex; pthread_mutex_t *themutex = mutex;

View File

@ -189,14 +189,50 @@ typedef enum
verifyable_object_state verifyable_object_isvalid (void const *, long); verifyable_object_state verifyable_object_isvalid (void const *, long);
verifyable_object_state verifyable_object_isvalid (void const *, long, void *); verifyable_object_state verifyable_object_isvalid (void const *, long, void *);
/* interface */
template <class ListNode> class List { template <class ListNode> class List {
public: public:
List(); List() : head(NULL)
void Insert (ListNode *aNode); {
ListNode *Remove ( ListNode *aNode); }
ListNode *Pop ();
void forEach (void (*)(ListNode *aNode)); void Insert (ListNode *aNode)
{
if (!aNode)
return;
aNode->next = (ListNode *) InterlockedExchangePointer (&head, aNode);
}
ListNode *Remove ( ListNode *aNode)
{
if (!aNode || !head)
return NULL;
if (aNode == head)
return Pop ();
ListNode *resultPrev = head;
while (resultPrev && resultPrev->next && !(aNode == resultPrev->next))
resultPrev = resultPrev->next;
if (resultPrev)
return (ListNode *)InterlockedExchangePointer (&resultPrev->next, resultPrev->next->next);
return NULL;
}
ListNode *Pop ()
{
return (ListNode *) InterlockedExchangePointer (&head, head->next);
}
/* poor mans generic programming. */
void forEach (void (ListNode::*callback) ())
{
ListNode *aNode = head;
while (aNode)
{
(aNode->*callback) ();
aNode = aNode->next;
}
}
protected: protected:
ListNode *head; ListNode *head;
}; };
@ -205,8 +241,6 @@ class pthread_key:public verifyable_object
{ {
public: public:
static bool isGoodObject (pthread_key_t const *); static bool isGoodObject (pthread_key_t const *);
static void runAllDestructors ();
DWORD dwTlsIndex; DWORD dwTlsIndex;
int set (const void *); int set (const void *);
@ -214,69 +248,32 @@ public:
pthread_key (void (*)(void *)); pthread_key (void (*)(void *));
~pthread_key (); ~pthread_key ();
static void fixup_before_fork(); static void fixup_before_fork()
static void fixup_after_fork(); {
keys.forEach (&pthread_key::saveKeyToBuffer);
}
static void fixup_after_fork()
{
keys.forEach (&pthread_key::recreateKeyFromBuffer);
}
static void runAllDestructors ()
{
keys.forEach (&pthread_key::runDestructor);
}
/* List support calls */ /* List support calls */
class pthread_key *next; class pthread_key *next;
private: private:
// lists of objects. USE THREADSAFE INSERTS AND DELETES.
static List<pthread_key> keys; static List<pthread_key> keys;
static void saveAKey (pthread_key *);
static void restoreAKey (pthread_key *);
static void destroyAKey (pthread_key *);
void saveKeyToBuffer (); void saveKeyToBuffer ();
void recreateKeyFromBuffer (); void recreateKeyFromBuffer ();
void (*destructor) (void *); void (*destructor) (void *);
void run_destructor (); void runDestructor ();
void *fork_buf; void *fork_buf;
}; };
/* implementation */
template <class ListNode>
List<ListNode>::List<ListNode> () : head(NULL)
{
}
template <class ListNode> void
List<ListNode>::Insert (ListNode *aNode)
{
if (!aNode)
return;
aNode->next = (ListNode *) InterlockedExchangePointer (&head, aNode);
}
template <class ListNode> ListNode *
List<ListNode>::Remove ( ListNode *aNode)
{
if (!aNode)
return NULL;
if (!head)
return NULL;
if (aNode == head)
return Pop ();
ListNode *resultPrev = head;
while (resultPrev && resultPrev->next && !(aNode == resultPrev->next))
resultPrev = resultPrev->next;
if (resultPrev)
return (ListNode *)InterlockedExchangePointer (&resultPrev->next, resultPrev->next->next);
return NULL;
}
template <class ListNode> ListNode *
List<ListNode>::Pop ()
{
return (ListNode *) InterlockedExchangePointer (&head, head->next);
}
/* poor mans generic programming. */
template <class ListNode> void
List<ListNode>::forEach (void (*callback)(ListNode *))
{
ListNode *aNode = head;
while (aNode)
{
callback (aNode);
aNode = aNode->next;
}
}
class pthread_attr:public verifyable_object class pthread_attr:public verifyable_object
{ {
public: public:
@ -319,7 +316,6 @@ public:
pthread_t owner; pthread_t owner;
int type; int type;
int pshared; int pshared;
class pthread_mutex * next;
pthread_t GetPthreadSelf () const pthread_t GetPthreadSelf () const
{ {
@ -358,18 +354,25 @@ public:
return 0; return 0;
} }
void fixup_after_fork ();
pthread_mutex (pthread_mutexattr * = NULL); pthread_mutex (pthread_mutexattr * = NULL);
pthread_mutex (pthread_mutex_t *, pthread_mutexattr *); pthread_mutex (pthread_mutex_t *, pthread_mutexattr *);
~pthread_mutex (); ~pthread_mutex ();
class pthread_mutex * next;
static void fixup_after_fork ()
{
mutexes.forEach (&pthread_mutex::FixupAfterFork);
}
void FixupAfterFork ();
private: private:
int _Lock (pthread_t self); int _Lock (pthread_t self);
int _TryLock (pthread_t self); int _TryLock (pthread_t self);
int _UnLock (pthread_t self); int _UnLock (pthread_t self);
int _Destroy (pthread_t self); int _Destroy (pthread_t self);
static List<pthread_mutex> mutexes;
static nativeMutex mutexInitializationLock; static nativeMutex mutexInitializationLock;
}; };
@ -506,16 +509,22 @@ public:
pthread_mutex_t mtxCond; pthread_mutex_t mtxCond;
class pthread_cond * next;
void UnBlock (const bool all); void UnBlock (const bool all);
int Wait (pthread_mutex_t mutex, DWORD dwMilliseconds = INFINITE); int Wait (pthread_mutex_t mutex, DWORD dwMilliseconds = INFINITE);
void fixup_after_fork ();
pthread_cond (pthread_condattr *); pthread_cond (pthread_condattr *);
~pthread_cond (); ~pthread_cond ();
class pthread_cond * next;
static void fixup_after_fork ()
{
conds.forEach (&pthread_cond::FixupAfterFork);
}
void FixupAfterFork ();
private: private:
static List<pthread_cond> conds;
static nativeMutex condInitializationLock; static nativeMutex condInitializationLock;
}; };
@ -562,14 +571,20 @@ public:
pthread_cond condReaders; pthread_cond condReaders;
pthread_cond condWriters; pthread_cond condWriters;
class pthread_rwlock * next;
void fixup_after_fork ();
pthread_rwlock (pthread_rwlockattr *); pthread_rwlock (pthread_rwlockattr *);
~pthread_rwlock (); ~pthread_rwlock ();
class pthread_rwlock * next;
static void fixup_after_fork ()
{
rwlocks.forEach (&pthread_rwlock::FixupAfterFork);
}
void FixupAfterFork ();
private: private:
static List<pthread_rwlock> rwlocks;
void addReader (struct RWLOCK_READER *rd); void addReader (struct RWLOCK_READER *rd);
void removeReader (struct RWLOCK_READER *rd); void removeReader (struct RWLOCK_READER *rd);
struct RWLOCK_READER *lookupReader (pthread_t thread); struct RWLOCK_READER *lookupReader (pthread_t thread);
@ -600,16 +615,25 @@ public:
static int post (sem_t * sem); static int post (sem_t * sem);
HANDLE win32_obj_id; HANDLE win32_obj_id;
class semaphore * next;
int shared; int shared;
long currentvalue; long currentvalue;
void Wait (); void Wait ();
void Post (); void Post ();
int TryWait (); int TryWait ();
void fixup_after_fork ();
semaphore (int, unsigned int); semaphore (int, unsigned int);
~semaphore (); ~semaphore ();
class semaphore * next;
static void fixup_after_fork ()
{
semaphores.forEach (&semaphore::FixupAfterFork);
}
void FixupAfterFork ();
private:
static List<semaphore> semaphores;
}; };
class callback class callback
@ -634,12 +658,6 @@ public:
callback *pthread_child; callback *pthread_child;
callback *pthread_parent; callback *pthread_parent;
// lists of pthread objects. USE THREADSAFE INSERTS AND DELETES.
class pthread_mutex * mutexs;
class pthread_cond * conds;
class pthread_rwlock * rwlocks;
class semaphore * semaphores;
pthread_key reent_key; pthread_key reent_key;
pthread_key thread_self_key; pthread_key thread_self_key;
@ -650,7 +668,6 @@ public:
MTinterface () : MTinterface () :
concurrency (0), threadcount (1), concurrency (0), threadcount (1),
pthread_prepare (NULL), pthread_child (NULL), pthread_parent (NULL), pthread_prepare (NULL), pthread_child (NULL), pthread_parent (NULL),
mutexs (NULL), conds (NULL), rwlocks (NULL), semaphores (NULL),
reent_key (NULL), thread_self_key (NULL) reent_key (NULL), thread_self_key (NULL)
{ {
} }