* cygwin.din: Add pthread_rwlock_destroy, pthread_rwlock_init,

pthread_rwlock_rdlock, pthread_rwlock_tryrdlock,
pthread_rwlock_wrlock, pthread_rwlock_trywrlock,
pthread_rwlock_unlock, pthread_rwlockattr_init,
pthread_rwlockattr_getpshared, pthread_rwlockattr_setpshared,
and pthread_rwlockattr_destroy.
* include/cygwin/version.h: Bump API minor number.
* include/pthread.h (PTHREAD_RWLOCK_INITIALIZER): Define a
reasonable value.
Add prototypes for pthread_rwlock_destroy, pthread_rwlock_init,
pthread_rwlock_rdlock, pthread_rwlock_tryrdlock,
pthread_rwlock_wrlock, pthread_rwlock_trywrlock,
pthread_rwlock_unlock, pthread_rwlockattr_init,
pthread_rwlockattr_getpshared, pthread_rwlockattr_setpshared,
and pthread_rwlockattr_destroy.
* thread.h (PTHREAD_ONCE_MAGIC): Remove superflous semicolon.
(PTHREAD_RWLOCK_MAGIC): New define.
(PTHREAD_RWLOCKATTR_MAGIC): Ditto.
(pthread_rwlockattr): New class.
(pthread_rwlock): Ditto.
(MTinterface::rwlocks): New member.
(MTinterface::MTinterface): Initialize rwlocks.
Add prototypes for __pthread_rwlock_destroy,
__pthread_rwlock_wrlock, __pthread_rwlock_trywrlock,
__pthread_rwlock_unlock, __pthread_rwlockattr_init,
__pthread_rwlockattr_getpshared, __pthread_rwlockattr_setpshared,
and __pthread_rwlockattr_destroy.
* thread.cc (MTinterface::Init): Initialize rwlock internal mutex.
(MTinterface::fixup_after_fork): Fixup rwlocks after fork.
(pthread_rwlockattr::isGoodObject): Implement.
(pthread_rwlockattr::pthread_rwlockattr): Ditto.
(pthread_rwlockattr::~pthread_rwlockattr): Ditto.
(pthread_rwlock::initMutex): Ditto.
(pthread_rwlock::pthread_rwlock): Ditto.
(pthread_rwlock::~pthread_rwlock): Ditto.
(pthread_rwlock::RdLock): Ditto.
(pthread_rwlock::TryRdLock): Ditto.
(pthread_rwlock::WrLock): Ditto.
(pthread_rwlock::TryWrLock): Ditto.
(pthread_rwlock::UnLock): Ditto.
(pthread_rwlock::addReader): Ditto.
(pthread_rwlock::removeReader): Ditto.
(pthread_rwlock::lookupReader): Ditto.
(pthread_rwlock::RdLockCleanup): Ditto.
(pthread_rwlock::WrLockCleanup): Ditto.
(pthread_rwlock::fixup_after_fork): Ditto.
(pthread_rwlock::isGoodObject): Ditto.
(pthread_rwlock::isGoodInitializer): Ditto.
(pthread_rwlock::isGoodInitializerOrObject): Ditto.
(pthread_rwlock::isGoodInitializerOrBadObject): Ditto.
(__pthread_rwlock_destroy): Ditto.
(pthread_rwlock::init): Ditto.
(__pthread_rwlock_rdlock): Ditto.
(__pthread_rwlock_tryrdlock): Ditto.
(__pthread_rwlock_wrlock): Ditto.
(__pthread_rwlock_trywrlock): Ditto.
This commit is contained in:
Thomas Pfaff 2003-03-18 20:01:07 +00:00
parent 5df1410028
commit 00d296a3f9
7 changed files with 761 additions and 3 deletions

View File

@ -1,3 +1,62 @@
2003-03-18 Thomas Pfaff <tpfaff@gmx.net>
* cygwin.din: Add pthread_rwlock_destroy, pthread_rwlock_init,
pthread_rwlock_rdlock, pthread_rwlock_tryrdlock,
pthread_rwlock_wrlock, pthread_rwlock_trywrlock,
pthread_rwlock_unlock, pthread_rwlockattr_init,
pthread_rwlockattr_getpshared, pthread_rwlockattr_setpshared,
and pthread_rwlockattr_destroy.
* include/cygwin/version.h: Bump API minor number.
* include/pthread.h (PTHREAD_RWLOCK_INITIALIZER): Define a
reasonable value.
Add prototypes for pthread_rwlock_destroy, pthread_rwlock_init,
pthread_rwlock_rdlock, pthread_rwlock_tryrdlock,
pthread_rwlock_wrlock, pthread_rwlock_trywrlock,
pthread_rwlock_unlock, pthread_rwlockattr_init,
pthread_rwlockattr_getpshared, pthread_rwlockattr_setpshared,
and pthread_rwlockattr_destroy.
* thread.h (PTHREAD_ONCE_MAGIC): Remove superflous semicolon.
(PTHREAD_RWLOCK_MAGIC): New define.
(PTHREAD_RWLOCKATTR_MAGIC): Ditto.
(pthread_rwlockattr): New class.
(pthread_rwlock): Ditto.
(MTinterface::rwlocks): New member.
(MTinterface::MTinterface): Initialize rwlocks.
Add prototypes for __pthread_rwlock_destroy,
__pthread_rwlock_wrlock, __pthread_rwlock_trywrlock,
__pthread_rwlock_unlock, __pthread_rwlockattr_init,
__pthread_rwlockattr_getpshared, __pthread_rwlockattr_setpshared,
and __pthread_rwlockattr_destroy.
* thread.cc (MTinterface::Init): Initialize rwlock internal mutex.
(MTinterface::fixup_after_fork): Fixup rwlocks after fork.
(pthread_rwlockattr::isGoodObject): Implement.
(pthread_rwlockattr::pthread_rwlockattr): Ditto.
(pthread_rwlockattr::~pthread_rwlockattr): Ditto.
(pthread_rwlock::initMutex): Ditto.
(pthread_rwlock::pthread_rwlock): Ditto.
(pthread_rwlock::~pthread_rwlock): Ditto.
(pthread_rwlock::RdLock): Ditto.
(pthread_rwlock::TryRdLock): Ditto.
(pthread_rwlock::WrLock): Ditto.
(pthread_rwlock::TryWrLock): Ditto.
(pthread_rwlock::UnLock): Ditto.
(pthread_rwlock::addReader): Ditto.
(pthread_rwlock::removeReader): Ditto.
(pthread_rwlock::lookupReader): Ditto.
(pthread_rwlock::RdLockCleanup): Ditto.
(pthread_rwlock::WrLockCleanup): Ditto.
(pthread_rwlock::fixup_after_fork): Ditto.
(pthread_rwlock::isGoodObject): Ditto.
(pthread_rwlock::isGoodInitializer): Ditto.
(pthread_rwlock::isGoodInitializerOrObject): Ditto.
(pthread_rwlock::isGoodInitializerOrBadObject): Ditto.
(__pthread_rwlock_destroy): Ditto.
(pthread_rwlock::init): Ditto.
(__pthread_rwlock_rdlock): Ditto.
(__pthread_rwlock_tryrdlock): Ditto.
(__pthread_rwlock_wrlock): Ditto.
(__pthread_rwlock_trywrlock): Ditto.
2003-03-18 Thomas Pfaff <tpfaff@gmx.net>
* thread.h (pthread_cond::ExitingWait): Remove.

View File

@ -954,6 +954,17 @@ pthread_mutexattr_setprotocol
pthread_mutexattr_setpshared
pthread_mutexattr_settype
pthread_once
pthread_rwlock_destroy
pthread_rwlock_init
pthread_rwlock_rdlock
pthread_rwlock_tryrdlock
pthread_rwlock_wrlock
pthread_rwlock_trywrlock
pthread_rwlock_unlock
pthread_rwlockattr_init
pthread_rwlockattr_getpshared
pthread_rwlockattr_setpshared
pthread_rwlockattr_destroy
pthread_self
pthread_setcancelstate
pthread_setcanceltype

View File

@ -192,12 +192,13 @@ details. */
aclsort32 acltomode32 acltopbits32 acltotext32 facl32
fgetpos64 fopen64 freopen64 fseeko64 fsetpos64 ftello64
_open64 _lseek64 _fstat64 _stat64 mknod32
80: Export pthread_rwlock stuff
*/
/* Note that we forgot to bump the api for ualarm, strtoll, strtoull */
#define CYGWIN_VERSION_API_MAJOR 0
#define CYGWIN_VERSION_API_MINOR 79
#define CYGWIN_VERSION_API_MINOR 80
/* There is also a compatibity version number associated with the
shared memory regions. It is incremented when incompatible

View File

@ -62,7 +62,7 @@ extern "C"
#define PTHREAD_PRIO_PROTECT
#define PTHREAD_PROCESS_SHARED 1
#define PTHREAD_PROCESS_PRIVATE 0
#define PTHREAD_RWLOCK_INITIALIZER
#define PTHREAD_RWLOCK_INITIALIZER (pthread_rwlock_t)22
/* process is the default */
#define PTHREAD_SCOPE_PROCESS 0
#define PTHREAD_SCOPE_SYSTEM 1
@ -161,6 +161,20 @@ int pthread_mutexattr_setprotocol (pthread_mutexattr_t *, int);
int pthread_mutexattr_setpshared (pthread_mutexattr_t *, int);
int pthread_mutexattr_settype (pthread_mutexattr_t *, int);
/* RW Locks */
int pthread_rwlock_destroy (pthread_rwlock_t *rwlock);
int pthread_rwlock_init (pthread_rwlock_t *rwlock, const pthread_rwlockattr_t *attr);
int pthread_rwlock_rdlock (pthread_rwlock_t *rwlock);
int pthread_rwlock_tryrdlock (pthread_rwlock_t *rwlock);
int pthread_rwlock_wrlock (pthread_rwlock_t *rwlock);
int pthread_rwlock_trywrlock (pthread_rwlock_t *rwlock);
int pthread_rwlock_unlock (pthread_rwlock_t *rwlock);
int pthread_rwlockattr_init (pthread_rwlockattr_t *rwlockattr);
int pthread_rwlockattr_getpshared (const pthread_rwlockattr_t *attr,
int *pshared);
int pthread_rwlockattr_setpshared (pthread_rwlockattr_t *attr, int pshared);
int pthread_rwlockattr_destroy (pthread_rwlockattr_t *rwlockattr);
int pthread_once (pthread_once_t *, void (*)(void));
/* Concurrency levels - X/Open interface */

View File

@ -388,6 +388,74 @@ pthread_condattr_setpshared (pthread_condattr_t * attr, int pshared)
return __pthread_condattr_setpshared (attr, pshared);
}
/* RW Locks */
int
pthread_rwlock_destroy (pthread_rwlock_t *rwlock)
{
return __pthread_rwlock_destroy (rwlock);
}
int
pthread_rwlock_init (pthread_rwlock_t *rwlock, const pthread_rwlockattr_t *attr)
{
return pthread_rwlock::init (rwlock, attr);
}
int
pthread_rwlock_rdlock (pthread_rwlock_t *rwlock)
{
return __pthread_rwlock_rdlock (rwlock);
}
int
pthread_rwlock_tryrdlock (pthread_rwlock_t *rwlock)
{
return __pthread_rwlock_tryrdlock (rwlock);
}
int
pthread_rwlock_wrlock (pthread_rwlock_t *rwlock)
{
return __pthread_rwlock_wrlock (rwlock);
}
int
pthread_rwlock_trywrlock (pthread_rwlock_t *rwlock)
{
return __pthread_rwlock_trywrlock (rwlock);
}
int
pthread_rwlock_unlock (pthread_rwlock_t *rwlock)
{
return __pthread_rwlock_unlock (rwlock);
}
int
pthread_rwlockattr_init (pthread_rwlockattr_t *rwlockattr)
{
return __pthread_rwlockattr_init (rwlockattr);
}
int
pthread_rwlockattr_getpshared (const pthread_rwlockattr_t *attr,
int *pshared)
{
return __pthread_rwlockattr_getpshared (attr, pshared);
}
int
pthread_rwlockattr_setpshared (pthread_rwlockattr_t *attr, int pshared)
{
return __pthread_rwlockattr_setpshared (attr, pshared);
}
int
pthread_rwlockattr_destroy (pthread_rwlockattr_t *rwlockattr)
{
return __pthread_rwlockattr_destroy (rwlockattr);
}
/* Scheduling */
int

View File

@ -199,6 +199,7 @@ MTinterface::Init (int forked)
pthread_mutex::initMutex ();
pthread_cond::initMutex ();
pthread_rwlock::initMutex ();
}
void
@ -230,6 +231,13 @@ MTinterface::fixup_after_fork (void)
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)
@ -998,6 +1006,341 @@ pthread_cond::fixup_after_fork ()
api_fatal ("pthread_cond::fixup_after_fork () failed to recreate win32 semaphore");
}
bool
pthread_rwlockattr::isGoodObject (pthread_rwlockattr_t const *attr)
{
if (verifyable_object_isvalid (attr, PTHREAD_RWLOCKATTR_MAGIC) != VALID_OBJECT)
return false;
return true;
}
pthread_rwlockattr::pthread_rwlockattr ():verifyable_object
(PTHREAD_RWLOCKATTR_MAGIC), shared (PTHREAD_PROCESS_PRIVATE)
{
}
pthread_rwlockattr::~pthread_rwlockattr ()
{
}
/* This is used for rwlock creation protection within a single process only */
nativeMutex NO_COPY pthread_rwlock::rwlockInitializationLock;
/* We can only be called once.
TODO: (no rush) use a non copied memory section to
hold an initialization flag. */
void
pthread_rwlock::initMutex ()
{
if (!rwlockInitializationLock.init ())
api_fatal ("Could not create win32 Mutex for pthread rwlock static initializer support.");
}
pthread_rwlock::pthread_rwlock (pthread_rwlockattr *attr) :
verifyable_object (PTHREAD_RWLOCK_MAGIC),
shared (0), waitingReaders (0), waitingWriters (0), writer (NULL),
readers (NULL), mtx (NULL), condReaders (NULL), condWriters (NULL),
next (NULL)
{
pthread_mutex *verifyable_mutex_obj = &mtx;
pthread_cond *verifyable_cond_obj;
if (attr)
if (attr->shared != PTHREAD_PROCESS_PRIVATE)
{
magic = 0;
return;
}
if (!pthread_mutex::isGoodObject (&verifyable_mutex_obj))
{
thread_printf ("Internal rwlock mutex is not valid. this %p", this);
magic = 0;
return;
}
/* Change the mutex type to NORMAL to speed up mutex operations */
mtx.type = PTHREAD_MUTEX_NORMAL;
verifyable_cond_obj = &condReaders;
if (!pthread_cond::isGoodObject (&verifyable_cond_obj))
{
thread_printf ("Internal rwlock readers cond is not valid. this %p", this);
magic = 0;
return;
}
verifyable_cond_obj = &condWriters;
if (!pthread_cond::isGoodObject (&verifyable_cond_obj))
{
thread_printf ("Internal rwlock writers cond is not valid. this %p", this);
magic = 0;
return;
}
/* threadsafe addition is easy */
next = (pthread_rwlock *) InterlockedExchangePointer (&MT_INTERFACE->rwlocks, this);
}
pthread_rwlock::~pthread_rwlock ()
{
/* I'm not 100% sure the next bit is threadsafe. I think it is... */
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
pthread_rwlock::RdLock ()
{
int result = 0;
struct RWLOCK_READER *reader;
pthread_t self = pthread::self ();
mtx.Lock ();
if (lookupReader (self))
{
result = EDEADLK;
goto DONE;
}
reader = new struct RWLOCK_READER;
if (!reader)
{
result = EAGAIN;
goto DONE;
}
while (writer || waitingWriters)
{
pthread_cleanup_push (pthread_rwlock::RdLockCleanup, this);
++waitingReaders;
condReaders.Wait (&mtx);
--waitingReaders;
pthread_cleanup_pop (0);
}
reader->thread = self;
addReader (reader);
DONE:
mtx.UnLock ();
return result;
}
int
pthread_rwlock::TryRdLock ()
{
int result = 0;
pthread_t self = pthread::self ();
mtx.Lock ();
if (writer || waitingWriters || lookupReader (self))
result = EBUSY;
else
{
struct RWLOCK_READER *reader = new struct RWLOCK_READER;
if (reader)
{
reader->thread = self;
addReader (reader);
}
else
result = EAGAIN;
}
mtx.UnLock ();
return result;
}
int
pthread_rwlock::WrLock ()
{
int result = 0;
pthread_t self = pthread::self ();
mtx.Lock ();
if (writer == self || lookupReader (self))
{
result = EDEADLK;
goto DONE;
}
while (writer || readers)
{
pthread_cleanup_push (pthread_rwlock::WrLockCleanup, this);
++waitingWriters;
condWriters.Wait (&mtx);
--waitingWriters;
pthread_cleanup_pop (0);
}
writer = self;
DONE:
mtx.UnLock ();
return result;
}
int
pthread_rwlock::TryWrLock ()
{
int result = 0;
pthread_t self = pthread::self ();
mtx.Lock ();
if (writer || readers)
result = EBUSY;
else
writer = self;
mtx.UnLock ();
return result;
}
int
pthread_rwlock::UnLock ()
{
int result = 0;
pthread_t self = pthread::self ();
mtx.Lock ();
if (writer)
{
if (writer != self)
{
result = EPERM;
goto DONE;
}
writer = NULL;
}
else
{
struct RWLOCK_READER *reader = lookupReader (self);
if (!reader)
{
result = EPERM;
goto DONE;
}
removeReader (reader);
delete reader;
}
if (waitingWriters)
{
if (!readers)
condWriters.UnBlock (false);
}
else if (waitingReaders)
condReaders.UnBlock (true);
DONE:
mtx.UnLock ();
return result;
}
void
pthread_rwlock::addReader (struct RWLOCK_READER *rd)
{
rd->next = (struct RWLOCK_READER *)
InterlockedExchangePointer (&readers, rd);
}
void
pthread_rwlock::removeReader (struct RWLOCK_READER *rd)
{
if (readers == rd)
InterlockedExchangePointer (&readers, rd->next);
else
{
struct RWLOCK_READER *temp = readers;
while (temp->next && temp->next != rd)
temp = temp->next;
/* but there may be a race between the loop above and this statement */
InterlockedExchangePointer (&temp->next, rd->next);
}
}
struct pthread_rwlock::RWLOCK_READER *
pthread_rwlock::lookupReader (pthread_t thread)
{
struct RWLOCK_READER *temp = readers;
while (temp && temp->thread != thread)
temp = temp->next;
return temp;
}
void
pthread_rwlock::RdLockCleanup (void *arg)
{
pthread_rwlock *rwlock = (pthread_rwlock *) arg;
--(rwlock->waitingReaders);
rwlock->mtx.UnLock ();
}
void
pthread_rwlock::WrLockCleanup (void *arg)
{
pthread_rwlock *rwlock = (pthread_rwlock *) arg;
--(rwlock->waitingWriters);
rwlock->mtx.UnLock ();
}
void
pthread_rwlock::fixup_after_fork ()
{
pthread_t self = pthread::self ();
struct RWLOCK_READER **temp = &readers;
waitingReaders = 0;
waitingWriters = 0;
/* Unlock eventually locked mutex */
mtx.UnLock ();
/*
* Remove all readers except self
*/
while (*temp)
{
if ((*temp)->thread == self)
temp = &((*temp)->next);
else
{
struct RWLOCK_READER *cur = *temp;
*temp = (*temp)->next;
delete cur;
}
}
}
/* pthread_key */
/* static members */
/* This stores pthread_key information across fork() boundaries */
@ -2292,6 +2635,191 @@ __pthread_condattr_destroy (pthread_condattr_t *condattr)
return 0;
}
/* RW locks */
bool
pthread_rwlock::isGoodObject (pthread_rwlock_t const *rwlock)
{
if (verifyable_object_isvalid (rwlock, PTHREAD_RWLOCK_MAGIC) != VALID_OBJECT)
return false;
return true;
}
bool
pthread_rwlock::isGoodInitializer (pthread_rwlock_t const *rwlock)
{
if (verifyable_object_isvalid (rwlock, PTHREAD_RWLOCK_MAGIC, PTHREAD_RWLOCK_INITIALIZER) != VALID_STATIC_OBJECT)
return false;
return true;
}
bool
pthread_rwlock::isGoodInitializerOrObject (pthread_rwlock_t const *rwlock)
{
if (verifyable_object_isvalid (rwlock, PTHREAD_RWLOCK_MAGIC, PTHREAD_RWLOCK_INITIALIZER) == INVALID_OBJECT)
return false;
return true;
}
bool
pthread_rwlock::isGoodInitializerOrBadObject (pthread_rwlock_t const *rwlock)
{
verifyable_object_state objectState = verifyable_object_isvalid (rwlock, PTHREAD_RWLOCK_MAGIC, PTHREAD_RWLOCK_INITIALIZER);
if (objectState == VALID_OBJECT)
return false;
return true;
}
int
__pthread_rwlock_destroy (pthread_rwlock_t *rwlock)
{
if (pthread_rwlock::isGoodInitializer (rwlock))
return 0;
if (!pthread_rwlock::isGoodObject (rwlock))
return EINVAL;
if ((*rwlock)->writer || (*rwlock)->readers ||
(*rwlock)->waitingReaders || (*rwlock)->waitingWriters)
return EBUSY;
delete (*rwlock);
*rwlock = NULL;
return 0;
}
int
pthread_rwlock::init (pthread_rwlock_t *rwlock, const pthread_rwlockattr_t *attr)
{
if (attr && !pthread_rwlockattr::isGoodObject (attr))
return EINVAL;
if (!rwlockInitializationLock.lock ())
return EINVAL;
if (!isGoodInitializerOrBadObject (rwlock))
{
rwlockInitializationLock.unlock ();
return EBUSY;
}
*rwlock = new pthread_rwlock (attr ? (*attr) : NULL);
if (!isGoodObject (rwlock))
{
delete (*rwlock);
*rwlock = NULL;
rwlockInitializationLock.unlock ();
return EAGAIN;
}
rwlockInitializationLock.unlock ();
return 0;
}
int
__pthread_rwlock_rdlock (pthread_rwlock_t *rwlock)
{
pthread_testcancel ();
if (pthread_rwlock::isGoodInitializer (rwlock))
pthread_rwlock::init (rwlock, NULL);
if (!pthread_rwlock::isGoodObject (rwlock))
return EINVAL;
return (*rwlock)->RdLock ();
}
int
__pthread_rwlock_tryrdlock (pthread_rwlock_t *rwlock)
{
if (pthread_rwlock::isGoodInitializer (rwlock))
pthread_rwlock::init (rwlock, NULL);
if (!pthread_rwlock::isGoodObject (rwlock))
return EINVAL;
return (*rwlock)->TryRdLock ();
}
int
__pthread_rwlock_wrlock (pthread_rwlock_t *rwlock)
{
pthread_testcancel ();
if (pthread_rwlock::isGoodInitializer (rwlock))
pthread_rwlock::init (rwlock, NULL);
if (!pthread_rwlock::isGoodObject (rwlock))
return EINVAL;
return (*rwlock)->WrLock ();
}
int
__pthread_rwlock_trywrlock (pthread_rwlock_t *rwlock)
{
if (pthread_rwlock::isGoodInitializer (rwlock))
pthread_rwlock::init (rwlock, NULL);
if (!pthread_rwlock::isGoodObject (rwlock))
return EINVAL;
return (*rwlock)->TryWrLock ();
}
int
__pthread_rwlock_unlock (pthread_rwlock_t *rwlock)
{
if (pthread_rwlock::isGoodInitializer (rwlock))
return 0;
if (!pthread_rwlock::isGoodObject (rwlock))
return EINVAL;
return (*rwlock)->UnLock ();
}
int
__pthread_rwlockattr_init (pthread_rwlockattr_t *rwlockattr)
{
if (check_valid_pointer (rwlockattr))
return EINVAL;
*rwlockattr = new pthread_rwlockattr;
if (!pthread_rwlockattr::isGoodObject (rwlockattr))
{
delete (*rwlockattr);
*rwlockattr = NULL;
return EAGAIN;
}
return 0;
}
int
__pthread_rwlockattr_getpshared (const pthread_rwlockattr_t *attr, int *pshared)
{
if (!pthread_rwlockattr::isGoodObject (attr))
return EINVAL;
*pshared = (*attr)->shared;
return 0;
}
int
__pthread_rwlockattr_setpshared (pthread_rwlockattr_t *attr, int pshared)
{
if (!pthread_rwlockattr::isGoodObject (attr))
return EINVAL;
if ((pshared < 0) || (pshared > 1))
return EINVAL;
/* shared rwlock vars not currently supported */
if (pshared != PTHREAD_PROCESS_PRIVATE)
return EINVAL;
(*attr)->shared = pshared;
return 0;
}
int
__pthread_rwlockattr_destroy (pthread_rwlockattr_t *rwlockattr)
{
if (!pthread_rwlockattr::isGoodObject (rwlockattr))
return EINVAL;
delete (*rwlockattr);
*rwlockattr = NULL;
return 0;
}
/* Thread signal */
int
__pthread_kill (pthread_t thread, int sig)

View File

@ -163,6 +163,8 @@ private:
#define PTHREAD_CONDATTR_MAGIC PTHREAD_MAGIC+6
#define SEM_MAGIC PTHREAD_MAGIC+7
#define PTHREAD_ONCE_MAGIC PTHREAD_MAGIC+8
#define PTHREAD_RWLOCK_MAGIC PTHREAD_MAGIC+9
#define PTHREAD_RWLOCKATTR_MAGIC PTHREAD_MAGIC+10
#define MUTEX_OWNER_ANONYMOUS ((pthread_t) -1)
@ -517,6 +519,67 @@ private:
static nativeMutex condInitializationLock;
};
class pthread_rwlockattr:public verifyable_object
{
public:
static bool isGoodObject(pthread_rwlockattr_t const *);
int shared;
pthread_rwlockattr ();
~pthread_rwlockattr ();
};
class pthread_rwlock:public verifyable_object
{
public:
static bool isGoodObject (pthread_rwlock_t const *);
static bool isGoodInitializer (pthread_rwlock_t const *);
static bool isGoodInitializerOrObject (pthread_rwlock_t const *);
static bool isGoodInitializerOrBadObject (pthread_rwlock_t const *);
static void initMutex ();
static int init (pthread_rwlock_t *, const pthread_rwlockattr_t *);
int shared;
unsigned long waitingReaders;
unsigned long waitingWriters;
pthread_t writer;
struct RWLOCK_READER
{
struct RWLOCK_READER *next;
pthread_t thread;
} *readers;
int RdLock ();
int TryRdLock ();
int WrLock ();
int TryWrLock ();
int UnLock ();
pthread_mutex mtx;
pthread_cond condReaders;
pthread_cond condWriters;
class pthread_rwlock * next;
void fixup_after_fork ();
pthread_rwlock (pthread_rwlockattr *);
~pthread_rwlock ();
private:
void addReader (struct RWLOCK_READER *rd);
void removeReader (struct RWLOCK_READER *rd);
struct RWLOCK_READER *lookupReader (pthread_t thread);
static void RdLockCleanup (void *arg);
static void WrLockCleanup (void *arg);
static nativeMutex rwlockInitializationLock;
};
class pthread_once
{
public:
@ -574,6 +637,7 @@ public:
// 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;
@ -586,7 +650,7 @@ public:
MTinterface () :
concurrency (0), threadcount (1),
pthread_prepare (NULL), pthread_child (NULL), pthread_parent (NULL),
mutexs (NULL), conds (NULL), semaphores (NULL),
mutexs (NULL), conds (NULL), rwlocks (NULL), semaphores (NULL),
reent_key (NULL), thread_self_key (NULL)
{
}
@ -632,6 +696,19 @@ int __pthread_condattr_getpshared (const pthread_condattr_t * attr,
int *pshared);
int __pthread_condattr_setpshared (pthread_condattr_t * attr, int pshared);
/* RW locks */
int __pthread_rwlock_destroy (pthread_rwlock_t *rwlock);
int __pthread_rwlock_rdlock (pthread_rwlock_t *rwlock);
int __pthread_rwlock_tryrdlock (pthread_rwlock_t *rwlock);
int __pthread_rwlock_wrlock (pthread_rwlock_t *rwlock);
int __pthread_rwlock_trywrlock (pthread_rwlock_t *rwlock);
int __pthread_rwlock_unlock (pthread_rwlock_t *rwlock);
int __pthread_rwlockattr_init (pthread_rwlockattr_t *rwlockattr);
int __pthread_rwlockattr_getpshared (const pthread_rwlockattr_t *attr,
int *pshared);
int __pthread_rwlockattr_setpshared (pthread_rwlockattr_t *attr, int pshared);
int __pthread_rwlockattr_destroy (pthread_rwlockattr_t *rwlockattr);
/* Thread signal */
int __pthread_kill (pthread_t thread, int sig);
int __pthread_sigmask (int operation, const sigset_t * set,