windows-pthread-rwlock-20081017

LICENSE MIT

Adds pthread rwlock support to the library.
This commit is contained in:
Jeffrey Altman 2008-10-17 21:24:19 +00:00 committed by Jeffrey Altman
parent c3251a3b18
commit e4b6e4d4a6
3 changed files with 221 additions and 0 deletions

View File

@ -33,6 +33,7 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <process.h>
#include <errno.h>
#include <sys/timeb.h>
@ -213,6 +214,201 @@ int pthread_mutex_destroy(pthread_mutex_t *mp) {
return rc;
}
int pthread_rwlock_destroy(pthread_rwlock_t *rwp)
{
int rc = 0;
if (rwp != NULL) {
pthread_mutex_destroy(&rwp->read_access_completion_mutex);
pthread_mutex_destroy(&rwp->write_access_mutex);
pthread_cond_destroy(&rwp->read_access_completion_wait);
} else {
#ifdef PTHREAD_DEBUG
DebugBreak();
#endif
rc = EINVAL;
}
return rc;
}
int pthread_rwlock_init(pthread_rwlock_t *rwp, const pthread_rwlockattr_t *attr)
{
int rc = 0;
if (rwp == NULL)
return EINVAL;
rwp->readers = 0;
rc = pthread_mutex_init(&rwp->write_access_mutex, NULL);
if (rc)
return rc;
rc = pthread_mutex_init(&rwp->read_access_completion_mutex, NULL);
if (rc)
goto error1;
rc = pthread_cond_init(&rwp->read_access_completion_wait, NULL);
if (rc == 0)
return 0; /* success */
pthread_mutex_destroy(&rwp->read_access_completion_mutex);
error1:
pthread_mutex_destroy(&rwp->write_access_mutex);
return rc;
}
int pthread_rwlock_wrlock(pthread_rwlock_t *rwp)
{
int rc = 0;
if (rwp == NULL)
return EINVAL;
if ((rc = pthread_mutex_lock(&rwp->write_access_mutex)) != 0)
return rc;
if ((rc = pthread_mutex_lock(&rwp->read_access_completion_mutex)) != 0)
{
pthread_mutex_unlock(&rwp->write_access_mutex);
return rc;
}
while (rc == 0 && rwp->readers > 0) {
rc = pthread_cond_wait( &rwp->read_access_completion_wait,
&rwp->read_access_completion_mutex);
}
pthread_mutex_unlock(&rwp->read_access_completion_mutex);
if (rc)
pthread_mutex_unlock(&rwp->write_access_mutex);
return rc;
}
int pthread_rwlock_rdlock(pthread_rwlock_t *rwp)
{
int rc = 0;
if (rwp == NULL)
return EINVAL;
if ((rc = pthread_mutex_lock(&rwp->write_access_mutex)) != 0)
return rc;
if ((rc = pthread_mutex_lock(&rwp->read_access_completion_mutex)) != 0)
{
pthread_mutex_unlock(&rwp->write_access_mutex);
return rc;
}
rwp->readers++;
pthread_mutex_unlock(&rwp->read_access_completion_mutex);
pthread_mutex_unlock(&rwp->write_access_mutex);
return rc;
}
int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwp)
{
int rc = 0;
if (rwp == NULL)
return EINVAL;
if ((rc = pthread_mutex_trylock(&rwp->write_access_mutex)) != 0)
return rc;
if ((rc = pthread_mutex_trylock(&rwp->read_access_completion_mutex)) != 0) {
pthread_mutex_unlock(&rwp->write_access_mutex);
return rc;
}
rwp->readers++;
pthread_mutex_unlock(&rwp->read_access_completion_mutex);
pthread_mutex_unlock(&rwp->write_access_mutex);
return rc;
}
int pthread_rwlock_trywrlock(pthread_rwlock_t *rwp)
{
int rc = 0;
if (rwp == NULL)
return EINVAL;
if ((rc = pthread_mutex_trylock(&rwp->write_access_mutex)) != 0)
return rc;
if ((rc = pthread_mutex_trylock(&rwp->read_access_completion_mutex)) != 0)
{
pthread_mutex_unlock(&rwp->write_access_mutex);
return rc;
}
if (rwp->readers > 0)
rc = EBUSY;
pthread_mutex_unlock(&rwp->read_access_completion_mutex);
if (rc)
pthread_mutex_unlock(&rwp->write_access_mutex);
return rc;
}
int pthread_rwlock_unlock(pthread_rwlock_t *rwp)
{
int rc = 0;
if (rwp == NULL)
return EINVAL;
rc = pthread_mutex_trylock(&rwp->write_access_mutex);
if (rc != EDEADLK)
{
/* unlock a read lock */
if (rc == 0)
pthread_mutex_unlock(&rwp->write_access_mutex);
if ((rc = pthread_mutex_lock(&rwp->read_access_completion_mutex)) != 0)
{
pthread_mutex_unlock(&rwp->write_access_mutex);
return rc;
}
if (rwp->readers <= 0)
{
rc = EINVAL;
}
else
{
if (--rwp->readers == 0)
pthread_cond_broadcast(&rwp->read_access_completion_wait);
}
pthread_mutex_unlock(&rwp->read_access_completion_mutex);
}
else
{
/* unlock a write lock */
rc = pthread_mutex_unlock(&rwp->write_access_mutex);
}
return rc;
}
/*
* keys is used to keep track of which keys are currently
* in use by the threads library. pthread_tsd_mutex is used

View File

@ -26,3 +26,10 @@ EXPORTS
pthread_attr_setdetachstate @24
pthread_exit @25
DllMain @26
pthread_rwlock_destroy @27
pthread_rwlock_init @28
pthread_rwlock_rdlock @29
pthread_rwlock_wrlock @30
pthread_rwlock_tryrdlock @31
pthread_rwlock_trywrlock @32
pthread_rwlock_unlock @33

View File

@ -31,6 +31,7 @@ typedef struct {
typedef int pthread_condattr_t;
typedef int pthread_mutexattr_t;
typedef int pthread_rwlockattr_t;
typedef int pthread_key_t;
typedef void *pthread_t;
@ -56,6 +57,13 @@ typedef struct {
struct rx_queue waiting_threads;
} pthread_cond_t;
typedef struct {
pthread_mutex_t write_access_mutex;
pthread_mutex_t read_access_completion_mutex;
pthread_cond_t read_access_completion_wait;
int readers;
} pthread_rwlock_t;
#define PTHREAD_ONCE_INIT {0,1}
extern int pthread_cond_broadcast(pthread_cond_t *cond);
@ -69,11 +77,21 @@ extern void *pthread_getspecific(pthread_key_t key);
extern int pthread_join(pthread_t target_thread, void **status);
extern int pthread_key_create(pthread_key_t *keyp, void (*destructor)(void *value));
extern int pthread_key_delete(pthread_key_t key);
extern int pthread_mutex_destroy(pthread_mutex_t *mp);
extern int pthread_mutex_init(pthread_mutex_t *mp, const pthread_mutexattr_t *attr);
extern int pthread_mutex_lock(pthread_mutex_t *mp);
extern int pthread_mutex_trylock(pthread_mutex_t *mp);
extern int pthread_mutex_unlock(pthread_mutex_t *mp);
extern int pthread_rwlock_destroy(pthread_rwlock_t *rwp);
extern int pthread_rwlock_init(pthread_rwlock_t *rwp, const pthread_rwlockattr_t *attr);
extern int pthread_rwlock_rdlock(pthread_rwlock_t *rwp);
extern int pthread_rwlock_wrlock(pthread_rwlock_t *rwp);
extern int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwp);
extern int pthread_rwlock_trywrlock(pthread_rwlock_t *rwp);
extern int pthread_rwlock_unlock(pthread_rwlock_t *rwp);
extern int pthread_once(pthread_once_t *once_control, void (*init_routine)(void));
extern int pthread_setspecific(pthread_key_t key, const void *value);
extern pthread_t pthread_self(void);