2 ** This basic implementation of Reader/Writer locks does not
3 ** protect writers from starvation. That is, if a writer is
4 ** currently waiting on a reader, any new reader will get
5 ** the lock before the writer.
8 /********************************************************
9 * An example source module to accompany...
11 * "Using POSIX Threads: Programming with Pthreads"
12 * by Brad nichols, Dick Buttlar, Jackie Farrell
13 * O'Reilly & Associates, Inc.
15 ********************************************************
18 * Library of functions implementing reader/writer locks
25 #include "ldap_pvt_thread.h"
28 ldap_pvt_thread_rdwr_init(ldap_pvt_thread_rdwr_t *rdwrp,
29 ldap_pvt_thread_rdwrattr_t *attrp)
31 rdwrp->readers_reading = 0;
32 rdwrp->writer_writing = 0;
33 ldap_pvt_thread_mutex_init(&(rdwrp->mutex), NULL );
34 ldap_pvt_thread_cond_init(&(rdwrp->lock_free), NULL );
38 int ldap_pvt_thread_rdwr_rlock(ldap_pvt_thread_rdwr_t *rdwrp){
39 ldap_pvt_thread_mutex_lock(&(rdwrp->mutex));
40 while(rdwrp->writer_writing) {
41 ldap_pvt_thread_cond_wait(&(rdwrp->lock_free),
44 rdwrp->readers_reading++;
45 ldap_pvt_thread_mutex_unlock(&(rdwrp->mutex));
49 int ldap_pvt_thread_rdwr_runlock(ldap_pvt_thread_rdwr_t *rdwrp)
51 ldap_pvt_thread_mutex_lock(&(rdwrp->mutex));
52 if (rdwrp->readers_reading == 0) {
53 ldap_pvt_thread_mutex_unlock(&(rdwrp->mutex));
57 rdwrp->readers_reading--;
58 if (rdwrp->readers_reading == 0) {
59 ldap_pvt_thread_cond_signal(&(rdwrp->lock_free));
61 ldap_pvt_thread_mutex_unlock(&(rdwrp->mutex));
66 int ldap_pvt_thread_rdwr_wlock(ldap_pvt_thread_rdwr_t *rdwrp)
68 ldap_pvt_thread_mutex_lock(&(rdwrp->mutex));
69 while(rdwrp->writer_writing || rdwrp->readers_reading) {
70 ldap_pvt_thread_cond_wait(&(rdwrp->lock_free),
73 rdwrp->writer_writing++;
74 ldap_pvt_thread_mutex_unlock(&(rdwrp->mutex));
78 int ldap_pvt_thread_rdwr_wunlock(ldap_pvt_thread_rdwr_t *rdwrp)
80 ldap_pvt_thread_mutex_lock(&(rdwrp->mutex));
81 if (rdwrp->writer_writing == 0) {
82 ldap_pvt_thread_mutex_unlock(&(rdwrp->mutex));
86 rdwrp->writer_writing = 0;
87 ldap_pvt_thread_cond_broadcast(&(rdwrp->lock_free));
88 ldap_pvt_thread_mutex_unlock(&(rdwrp->mutex));
96 * return 0 if false, suitable for assert(ldap_pvt_thread_rdwr_Xchk(rdwr))
98 * Currently they don't check if the calling thread is the one
99 * that has the lock, just that there is a reader or writer.
101 * Basically sufficent for testing that places that should have
105 int ldap_pvt_thread_rdwr_rchk(ldap_pvt_thread_rdwr_t *rdwrp)
107 return(rdwrp->readers_reading!=0);
110 int ldap_pvt_thread_rdwr_wchk(ldap_pvt_thread_rdwr_t *rdwrp)
112 return(rdwrp->writer_writing!=0);
114 int ldap_pvt_thread_rdwr_rwchk(ldap_pvt_thread_rdwr_t *rdwrp)
116 return(ldap_pvt_thread_rdwr_rchk_np(rdwrp) ||
117 ldap_pvt_thread_rdwr_wchk_np(rdwrp));
120 #endif /* LDAP_DEBUG */