Anonymous avatar Anonymous committed 1bfc5aa

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

Converted the appropriate functions to return int instead of void.

Comments (0)

Files changed (4)

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
 

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

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);
 

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
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.