558  

void

waiting_writer_cleanup (void *arg)

{

rwlock *1;

1 = (rwlock *) arg;

if ((--1->waiting_writers == 0) && (1->lock_count >= 0)) {
/*

*       .

*/
pthread_cond_broadcast (&l->wcond) ;

}

pthread_mutex_unlock (&l->lock) ;

}

void

lock_for_write (rwlock *1)

{

pthread_mutex_lock (&l->lock) ;

1->waiting_writers++;

pthread_cleanup_push (waiting_writer_cleanup, 1);

while (1->lock_count ! =0)

pthread_cond_wait (&l->wcond, &l->lock) ;

1->lock_count = -1;

/*

*    ,   pthread_cleanup_pop()

*    waiting_writer_cleanup().

*/

pthread_cleanup_pop (1) ;

}

void

release_write_lock (rwlock *1)

{

pthread_mutex_lock (&l->lock) ;

1->lock_count = 0;

if (1->waiting_writers == 0)

pthread_cond_broadcast (&1->rcond)

else

pthread_cond_signal (&l->wcond) ;

pthread_mutex_unlock (&l->lock) ;

}
/*

*      

* -.

*/

void

initialize_rwlock (rwlock *1)

{

pthread_mutex_init (&l->lock, pthread_mutexattr_default) ;

pthread_cond_init (&l->wcond, pthread_condattr_default) ;

pthread_cond_init (&l->rcond, pthread_condattr_default) ;

1->lock_count = 0;

1->waiting_writers = 0;