Commits

shl...@52c325ad-5fd0-0310-8a0f-c43feede02cc  committed 1bfc5aa

Interface change! Now waiting for all threads to finish before destroying.

Converted the appropriate functions to return int instead of void.

  • Participants
  • Parent commits 291a433

Comments (0)

Files changed (4)

File pthreads/man/pthread_rwlock_fcfs.pod

 
 B<pthread_rwlock_fcfs_t> * I<rwlock> = B<pthread_rwlock_fcfs_alloc>();
 
-B<void> B<pthread_rwlock_fcfs_gain_read>(B<pthread_rwlock_fcfs_t> * I<rwlock>);
+B<int> B<pthread_rwlock_fcfs_gain_read>(B<pthread_rwlock_fcfs_t> * I<rwlock>);
 
-B<void> B<pthread_rwlock_fcfs_gain_write>(B<pthread_rwlock_fcfs_t> * I<rwlock>);
+B<int> B<pthread_rwlock_fcfs_gain_write>(B<pthread_rwlock_fcfs_t> * I<rwlock>);
 
-B<void> B<pthread_rwlock_fcfs_try_gain_read>(B<pthread_rwlock_fcfs_t> * I<rwlock>);
+B<int> B<pthread_rwlock_fcfs_try_gain_read>(B<pthread_rwlock_fcfs_t> * I<rwlock>);
 
-B<void> B<pthread_rwlock_fcfs_try_gain_write>(B<pthread_rwlock_fcfs_t> * I<rwlock>);
+B<int> B<pthread_rwlock_fcfs_try_gain_write>(B<pthread_rwlock_fcfs_t> * I<rwlock>);
 
 B<int> B<pthread_rwlock_fcfs_timed_gain_read>(B<pthread_rwlock_fcfs_t> * I<rwlock>, B<const struct timespec> * I<abstime>, B<int> (*I<continue_callback>)(B<void> * context), B<void> * I<context>);
 
 
 B<pthread_rwlock_fcfs_gain_read> and B<pthread_rwlock_fcfs_gain_write> can be
 used to gain read or write access for I<rwlock>. They block indefinitely until
-the access is granted.
+the access is granted. They return 0 on success or -1 if the lock is
+going to be destroyed and should no longer be accessed.
 
 B<pthread_rwlock_fcfs_try_gain_read> and B<pthread_rwlock_fcfs_try_gain_write>
 attempt to gain a read or write permission and if they do not succeed they 
-exit immediately. They return 0 upon success and non-zero otherwise.
+exit immediately. They return 0 upon success, -1 if the lock is going
+to be destroyed, and non-zero otherwise.
 
 B<pthread_rwlock_fcfs_timed_gain_read> and B<pthread_rwlock_fcfs_timed_gain_write> 
 attempt to gain a permission while initially waiting until I<abstime>. If by 
 function will terminate once the initial wait is over. 
 
 B<pthread_rwlock_fcfs_timed_gain_read> and B<pthread_rwlock_fcfs_timed_gain_write> 
-return 0 upon success and 1 if they failed to gain a read or write permission.
+return 0 upon success, 1 if they failed to gain a read or write permission
+and -1 if the lock is going to be destroyed.
 
 B<pthread_rwlock_fcfs_release> releases a previously granted 
 read or write permission.
 
 =head1 RETURN VALUE
 
-All condition variable functions return 0 on success and a non-zero error
-code on error.
+All the rwlock functions return 0 on success, -1 if the rwlock is going
+to be destroyed, and a non-zero error code on error.
 
 =head1 AUTHOR
 

File pthreads/pthread/rwlock_fcfs.h

 /*
  * Wait indefinitely until a read access to the lock is granted.
  * */
-extern void pthread_rwlock_fcfs_gain_read(pthread_rwlock_fcfs_t * rwlock PTHREAD_RWLOCK_FCFS_DEBUG_ARGS);
+extern int pthread_rwlock_fcfs_gain_read(pthread_rwlock_fcfs_t * rwlock PTHREAD_RWLOCK_FCFS_DEBUG_ARGS);
 
 /*
  * Wait indefinitely until a write access to the lock is granted.
  * */
-extern void pthread_rwlock_fcfs_gain_write(pthread_rwlock_fcfs_t * rwlock PTHREAD_RWLOCK_FCFS_DEBUG_ARGS);
+extern int pthread_rwlock_fcfs_gain_write(pthread_rwlock_fcfs_t * rwlock PTHREAD_RWLOCK_FCFS_DEBUG_ARGS);
 
 /*
  * Release a previously gained read or write access

File pthreads/rwlock.c

 
 static int gain_write_generic(
     pthread_rwlock_fcfs_t * rwlock,
+    int write_for_destroy,
     int wait_for_access,
     int is_timed,
     const struct timespec * abstime,
     void * context
     )
 {
+    /* If the rwlock is going to be destroyed - exit now. 
+     * An exception is if we are gaining write access to clear up all
+     * existing threads.
+     * */
+    if (rwlock->is_destroyed && !write_for_destroy)
+    {
+        return -1;
+    }
+
     /* If there aren't any readers or writers in the queue we
      * can gain access immidiately */
     if (rwlock->is_writer || (rwlock->num_readers > 0))
 }
 
 
-void pthread_rwlock_fcfs_gain_write(pthread_rwlock_fcfs_t * rwlock PTHREAD_RWLOCK_FCFS_DEBUG_ARGS)
+int pthread_rwlock_fcfs_gain_write(pthread_rwlock_fcfs_t * rwlock PTHREAD_RWLOCK_FCFS_DEBUG_ARGS)
 {
+    int ret;
+
     pthread_mutex_lock(&(rwlock->mutex));
 
     my_debug_print(rwlock, id, "Want Lock!");
 
-    gain_write_generic(rwlock, 1, 0, NULL, NULL, NULL);
+    ret = gain_write_generic(rwlock, 0, 1, 0, NULL, NULL, NULL);
 
     my_debug_print(rwlock, id, "Lock!");
 
     pthread_mutex_unlock(&(rwlock->mutex));
+
+    return ret;
+}
+
+static int gain_write_for_destroy(pthread_rwlock_fcfs_t * rwlock PTHREAD_RWLOCK_FCFS_DEBUG_ARGS)
+{
+    int ret;
+
+    pthread_mutex_lock(&(rwlock->mutex));
+
+    my_debug_print(rwlock, id, "Want Lock!");
+
+    ret = gain_write_generic(rwlock, 1, 1, 0, NULL, NULL, NULL);
+
+    my_debug_print(rwlock, id, "Lock!");
+
+    pthread_mutex_unlock(&(rwlock->mutex));
+
+    return ret;
 }
 
 int pthread_rwlock_fcfs_try_gain_write(pthread_rwlock_fcfs_t * rwlock PTHREAD_RWLOCK_FCFS_DEBUG_ARGS)
 
     my_debug_print(rwlock, id, "Want Try Lock!");
 
-    ret = gain_write_generic(rwlock, 0, 0, NULL, NULL, NULL);
+    ret = gain_write_generic(rwlock, 0, 0, 0, NULL, NULL, NULL);
 
     my_debug_print(rwlock, id, ((ret == 0)? "Lock!" : "Failed Lock!"));
 
 
     my_debug_print(rwlock, id, "Want Timed Lock!");
 
-    ret = gain_write_generic(rwlock, 1, 1, abstime, continue_callback, context);
+    ret = gain_write_generic(rwlock, 0, 1, 1, abstime, continue_callback, context);
 
     my_debug_print(rwlock, id, ((ret == 0)?"Lock!": "Failed Lock!"));
 
     void * context
     )
 {
+    /* If the rwlock is going to be destroyed - exit now. */
+    if (rwlock->is_destroyed)
+    {
+        return -1;
+    }
     /*
      * It is possible that there are some disabled items clogging the
      * queue, which will prevent this thread from being accepted immidiately.
     return ret;
 }
 
-void pthread_rwlock_fcfs_gain_read(pthread_rwlock_fcfs_t * rwlock PTHREAD_RWLOCK_FCFS_DEBUG_ARGS)
+int pthread_rwlock_fcfs_gain_read(pthread_rwlock_fcfs_t * rwlock PTHREAD_RWLOCK_FCFS_DEBUG_ARGS)
 {
+    int ret;
+
     pthread_mutex_lock(&(rwlock->mutex));
 
     my_debug_print(rwlock, id, "Want Lock!");
 
-    gain_read_generic(rwlock, 1, 0, NULL, NULL, NULL);
+    ret = gain_read_generic(rwlock, 1, 0, NULL, NULL, NULL);
 
     my_debug_print(rwlock, id, "Lock!");
 
     pthread_mutex_unlock(&(rwlock->mutex));
+
+    return ret;
 }
 
 int pthread_rwlock_fcfs_try_gain_read(pthread_rwlock_fcfs_t * rwlock PTHREAD_RWLOCK_FCFS_DEBUG_ARGS)
     rwlock->is_destroyed = 1;
 
     /* Make sure all running threads are cleared up. */
-    pthread_rwlock_fcfs_gain_write(rwlock PTHREAD_RWLOCK_FCFS_DEBUG_CALL_ARGS);
+    gain_write_for_destroy(rwlock PTHREAD_RWLOCK_FCFS_DEBUG_CALL_ARGS);
 
     pthread_rwlock_fcfs_release(rwlock PTHREAD_RWLOCK_FCFS_DEBUG_CALL_ARGS);
 

File pthreads/rwlock_fcfs.h

 /*
  * Wait indefinitely until a read access to the lock is granted.
  * */
-extern void pthread_rwlock_fcfs_gain_read(pthread_rwlock_fcfs_t * rwlock PTHREAD_RWLOCK_FCFS_DEBUG_ARGS);
+extern int pthread_rwlock_fcfs_gain_read(pthread_rwlock_fcfs_t * rwlock PTHREAD_RWLOCK_FCFS_DEBUG_ARGS);
 
 /*
  * Wait indefinitely until a write access to the lock is granted.
  * */
-extern void pthread_rwlock_fcfs_gain_write(pthread_rwlock_fcfs_t * rwlock PTHREAD_RWLOCK_FCFS_DEBUG_ARGS);
+extern int pthread_rwlock_fcfs_gain_write(pthread_rwlock_fcfs_t * rwlock PTHREAD_RWLOCK_FCFS_DEBUG_ARGS);
 
 /*
  * Release a previously gained read or write access