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 )
30 rdwrp->lt_readers_reading = 0;
31 rdwrp->lt_writer_writing = 0;
32 ldap_pvt_thread_mutex_init(&(rdwrp->lt_mutex) );
33 ldap_pvt_thread_cond_init(&(rdwrp->lt_lock_free) );
38 ldap_pvt_thread_rdwr_destroy(ldap_pvt_thread_rdwr_t *rdwrp )
40 ldap_pvt_thread_mutex_destroy(&(rdwrp->lt_mutex) );
41 ldap_pvt_thread_cond_destroy(&(rdwrp->lt_lock_free) );
45 int ldap_pvt_thread_rdwr_rlock(ldap_pvt_thread_rdwr_t *rdwrp){
46 ldap_pvt_thread_mutex_lock(&(rdwrp->lt_mutex));
47 while(rdwrp->lt_writer_writing) {
48 ldap_pvt_thread_cond_wait(&(rdwrp->lt_lock_free),
51 rdwrp->lt_readers_reading++;
52 ldap_pvt_thread_mutex_unlock(&(rdwrp->lt_mutex));
56 int ldap_pvt_thread_rdwr_runlock(ldap_pvt_thread_rdwr_t *rdwrp)
58 ldap_pvt_thread_mutex_lock(&(rdwrp->lt_mutex));
59 if (rdwrp->lt_readers_reading == 0) {
60 ldap_pvt_thread_mutex_unlock(&(rdwrp->lt_mutex));
64 rdwrp->lt_readers_reading--;
65 if (rdwrp->lt_readers_reading == 0) {
66 ldap_pvt_thread_cond_signal(&(rdwrp->lt_lock_free));
68 ldap_pvt_thread_mutex_unlock(&(rdwrp->lt_mutex));
73 int ldap_pvt_thread_rdwr_wlock(ldap_pvt_thread_rdwr_t *rdwrp)
75 ldap_pvt_thread_mutex_lock(&(rdwrp->lt_mutex));
76 while(rdwrp->lt_writer_writing || rdwrp->lt_readers_reading) {
77 ldap_pvt_thread_cond_wait(&(rdwrp->lt_lock_free),
80 rdwrp->lt_writer_writing++;
81 ldap_pvt_thread_mutex_unlock(&(rdwrp->lt_mutex));
85 int ldap_pvt_thread_rdwr_wunlock(ldap_pvt_thread_rdwr_t *rdwrp)
87 ldap_pvt_thread_mutex_lock(&(rdwrp->lt_mutex));
88 if (rdwrp->lt_writer_writing == 0) {
89 ldap_pvt_thread_mutex_unlock(&(rdwrp->lt_mutex));
93 rdwrp->lt_writer_writing = 0;
94 ldap_pvt_thread_cond_broadcast(&(rdwrp->lt_lock_free));
95 ldap_pvt_thread_mutex_unlock(&(rdwrp->lt_mutex));
103 * return 0 if false, suitable for assert(ldap_pvt_thread_rdwr_Xchk(rdwr))
105 * Currently they don't check if the calling thread is the one
106 * that has the lock, just that there is a reader or writer.
108 * Basically sufficent for testing that places that should have
112 int ldap_pvt_thread_rdwr_rchk(ldap_pvt_thread_rdwr_t *rdwrp)
114 return(rdwrp->lt_readers_reading!=0);
117 int ldap_pvt_thread_rdwr_wchk(ldap_pvt_thread_rdwr_t *rdwrp)
119 return(rdwrp->lt_writer_writing!=0);
121 int ldap_pvt_thread_rdwr_rwchk(ldap_pvt_thread_rdwr_t *rdwrp)
123 return(ldap_pvt_thread_rdwr_rchk(rdwrp) ||
124 ldap_pvt_thread_rdwr_wchk(rdwrp));
127 #endif /* LDAP_DEBUG */