]> git.sur5r.net Git - openldap/blob - libraries/liblthread/rdwr.c
Add basic NT thread support.
[openldap] / libraries / liblthread / rdwr.c
1 /*
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.
6 */
7
8 /********************************************************
9  * An example source module to accompany...
10  *
11  * "Using POSIX Threads: Programming with Pthreads"
12  *               by Brad nichols, Dick Buttlar, Jackie Farrell
13  *               O'Reilly & Associates, Inc.
14  *
15  ********************************************************
16  * rdwr.c --
17  * 
18  * Library of functions implementing reader/writer locks
19  */
20
21 #include <portable.h>
22
23 #include <stdlib.h>
24
25 #include <lthread.h>
26 #include <lthread_rdwr.h>
27
28 int pthread_rdwr_init_np(pthread_rdwr_t *rdwrp, pthread_rdwrattr_t *attrp)
29 {
30         rdwrp->readers_reading = 0;
31         rdwrp->writer_writing = 0;
32         pthread_mutex_init(&(rdwrp->mutex), pthread_mutexattr_default);
33         pthread_cond_init(&(rdwrp->lock_free), pthread_condattr_default);
34         return 0;
35 }
36
37 int pthread_rdwr_rlock_np(pthread_rdwr_t *rdwrp){
38         pthread_mutex_lock(&(rdwrp->mutex));
39         while(rdwrp->writer_writing) {
40                 pthread_cond_wait(&(rdwrp->lock_free), &(rdwrp->mutex));
41         }
42         rdwrp->readers_reading++;
43         pthread_mutex_unlock(&(rdwrp->mutex));
44         return 0;
45 }
46
47 int pthread_rdwr_runlock_np(pthread_rdwr_t *rdwrp)
48 {
49         pthread_mutex_lock(&(rdwrp->mutex));
50         if (rdwrp->readers_reading == 0) {
51                 pthread_mutex_unlock(&(rdwrp->mutex));
52                 return -1;
53         }
54         else {
55                 rdwrp->readers_reading--;
56                 if (rdwrp->readers_reading == 0) {
57                         pthread_cond_signal(&(rdwrp->lock_free));
58                 }
59                 pthread_mutex_unlock(&(rdwrp->mutex));
60                 return 0;
61         }
62 }
63
64 int pthread_rdwr_wlock_np(pthread_rdwr_t *rdwrp)
65 {
66         pthread_mutex_lock(&(rdwrp->mutex));
67         while(rdwrp->writer_writing || rdwrp->readers_reading) {
68                 pthread_cond_wait(&(rdwrp->lock_free), &(rdwrp->mutex));
69         }
70         rdwrp->writer_writing++;
71         pthread_mutex_unlock(&(rdwrp->mutex));
72         return 0;
73 }
74
75 int pthread_rdwr_wunlock_np(pthread_rdwr_t *rdwrp)
76 {
77         pthread_mutex_lock(&(rdwrp->mutex));
78         if (rdwrp->writer_writing == 0) {
79                 pthread_mutex_unlock(&(rdwrp->mutex));
80                 return -1;
81         }
82         else {
83                 rdwrp->writer_writing = 0;
84                 pthread_cond_broadcast(&(rdwrp->lock_free));
85                 pthread_mutex_unlock(&(rdwrp->mutex));
86                 return 0;
87         }
88 }
89
90 #ifdef LDAP_DEBUG
91
92 /* just for testing, 
93  * return 0 if false, suitable for assert(pthread_rdwr_Xchk(rdwr))
94  * 
95  * Currently they don't check if the calling thread is the one 
96  * that has the lock, just that there is a reader or writer.
97  *
98  * Basically sufficent for testing that places that should have
99  * a lock are caught.
100  */
101
102 int pthread_rdwr_rchk_np(pthread_rdwr_t *rdwrp)
103 {
104         return(rdwrp->readers_reading!=0);
105 }
106
107 int pthread_rdwr_wchk_np(pthread_rdwr_t *rdwrp)
108 {
109         return(rdwrp->writer_writing!=0);
110 }
111 int pthread_rdwr_rwchk_np(pthread_rdwr_t *rdwrp)
112 {
113         return(pthread_rdwr_rchk_np(rdwrp) || pthread_rdwr_wchk_np(rdwrp));
114 }
115
116 #endif /* LDAP_DEBUG */