/* ******************************************************************************* * Copyright (c) 1996 Martin Poole * ******************************************************************************* ** ** WARNING !! WARNING !! WARNING !! WARNING !! WARNING !! WARNING !! ** ** Any changes to be made to this file should first be checked with ** mplib1 source control for library integrity. ** ** mplib1 source control can be reached at mplib1@quatermass.co.uk ** * * $Source: /home/cvs/cvsroot/onelan/onelan/src/mplib1/libsrc/bpo_lock_rw.c,v $ * $Author: mpoole $ * $Date: 2002/10/07 09:37:37 $ * $Revision: 1.2 $ * ******************************************************************************* * * Change History * * $Log: bpo_lock_rw.c,v $ * Revision 1.2 2002/10/07 09:37:37 mpoole * Initial checkin of mplib1-3.1.0 * * Revision 1.1 2002/10/07 09:36:54 mpoole * Initial checkin of mplib1-3.1.0 * * ******************************************************************************* */ #ident "$Header: /home/cvs/cvsroot/onelan/onelan/src/mplib1/libsrc/bpo_lock_rw.c,v 1.2 2002/10/07 09:37:37 mpoole Exp $" /* ------------------------------------------------------------------ Include files ------------------------------------------------------------------ */ #include #include #include #include #include #include #include #include #include /* ------------------------------------------------------------------ defines ------------------------------------------------------------------ */ /* ------------------------------------------------------------------ Code starts here ------------------------------------------------------------------ */ /* Now I want to devise a lock structure for bpo_Full_Lists. I want to enable multiple readers, but only allow a single writer. I also want to ensure that once a writer is waiting to gain control, all new readers are blocked until the write process has done its work. */ void bpo_RLock( struct bpo_fl_lock *bflp ) { /* time to obtain the read lock */ do { b_Lock( &bflp->bpo_fl_lock ); if (bflp->w_cnt) { b_Unlock( &bflp->bpo_fl_lock ); while (bflp->w_cnt) bpo_take_a_nap(); }else { bflp->r_cnt++; b_Unlock( &bflp->bpo_fl_lock ); break; } } while(1); return; } void bpo_WLock( struct bpo_fl_lock *bflp) { /* get the write lock */ do { while (bflp->w_cnt) bpo_take_a_nap(); b_Lock( &bflp->bpo_fl_lock ); if (bflp->w_cnt == 0) break; b_Unlock( &bflp->bpo_fl_lock ); } while(1); bflp->w_cnt++; if (bflp->r_cnt) { b_Unlock( &bflp->bpo_fl_lock ); while (bflp->r_cnt) bpo_take_a_nap(); b_Lock( &bflp->bpo_fl_lock ); } bflp->w_cnt++; b_Unlock( &bflp->bpo_fl_lock ); return; } void bpo_RUnlock( struct bpo_fl_lock *bflp ) { /* just decrement the r_cnt */ b_Lock( &bflp->bpo_fl_lock ); bflp->r_cnt--; b_Unlock( &bflp->bpo_fl_lock ); return; } void bpo_WUnlock( struct bpo_fl_lock *bflp ) { b_Lock( &bflp->bpo_fl_lock ); bflp->w_cnt = 0; b_Unlock( &bflp->bpo_fl_lock ); return; } int bpo_RWLock( struct bpo_fl_lock *bflp ) { int rv; b_Lock( &bflp->bpo_fl_lock ); if (bflp->w_cnt == 0) { /* Got it! */ bflp->r_cnt--; /* we're not reading anymore */ bflp->w_cnt++; /* and set write pending */ b_Unlock( &bflp->bpo_fl_lock ); while (bflp->r_cnt) bpo_take_a_nap(); b_Lock( &bflp->bpo_fl_lock ); bflp->w_cnt++; rv = 1; }else rv = 0; b_Unlock( &bflp->bpo_fl_lock ); return(rv); } void bpo_WRLock( struct bpo_fl_lock *bflp ) { b_Lock( &bflp->bpo_fl_lock ); bflp->w_cnt = 0; bflp->r_cnt++; b_Unlock( &bflp->bpo_fl_lock ); return; } void bpo_Init_RWLock( struct bpo_fl_lock *bflp ) { bflp->w_cnt = 0; bflp->r_cnt = 0; b_Init( &bflp->bpo_fl_lock ); return; } /* -- End of File -- */