mirror of
https://git.openafs.org/openafs.git
synced 2025-01-19 23:40:13 +00:00
windows-pthread-rwlock-20081017
LICENSE MIT Adds pthread rwlock support to the library.
This commit is contained in:
parent
c3251a3b18
commit
e4b6e4d4a6
@ -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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user