changeset 1375:8a5eb4ab7bf5

* src/mqueue.cxx: Fix problem with mq_timedsend() and mq_timedreceive() timing out with zero timeouts even when there is room in the queue. * src/pthread.cxx (pthread_exit): Added code to disable cancellation requests during thread exit. This allows thread cleanup handlers to issue system calls when cleaning up thread resources.
author nickg
date Fri, 21 Nov 2003 10:53:11 +0000
parents 0db10af9ebb7
children acb537d1d1d8
files packages/compat/posix/current/ChangeLog packages/compat/posix/current/src/mqueue.cxx packages/compat/posix/current/src/pthread.cxx
diffstat 3 files changed, 42 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- a/packages/compat/posix/current/ChangeLog
+++ b/packages/compat/posix/current/ChangeLog
@@ -1,3 +1,15 @@
+2003-11-19  Rickard Westman <rickard.westman@27m.se>
+	
+	* src/mqueue.cxx: Fix problem with mq_timedsend() and
+	mq_timedreceive() timing out with zero timeouts even when there is
+	room in the queue.
+
+2003-11-17  Dan Jakubiec <djakubiec@yahoo.com>
+
+	* src/pthread.cxx (pthread_exit): Added code to disable cancellation
+	requests during thread exit.  This allows thread cleanup handlers
+	to issue system calls when cleaning up thread resources.
+
 2003-06-18  Jonathan Larmour  <jifl@eCosCentric.com>
 
 	* src/pthread.cxx (pthread_self_info): Just add some comments so
--- a/packages/compat/posix/current/src/mqueue.cxx
+++ b/packages/compat/posix/current/src/mqueue.cxx
@@ -723,9 +723,18 @@ mq_timedsend( mqd_t mqdes, const char *m
     bool nonblocking = ((user->flags & O_NONBLOCK) == O_NONBLOCK);
     bool badtimespec = (abs_timeout->tv_nsec < 0) ||
         (abs_timeout->tv_nsec > 999999999l);
-    err = tabent->mq->put( msg_ptr, msg_len, msg_prio,
-                           !nonblocking && !badtimespec,
-                           cyg_timespec_to_ticks(abs_timeout));
+    cyg_tick_count abs_ticks = cyg_timespec_to_ticks(abs_timeout);
+
+    // We should never time out if there is room in the queue.  Simplest
+    // way to ensure this is to try the non-blocking put() first.
+    err = tabent->mq->put( msg_ptr, msg_len, msg_prio, false, abs_ticks );
+
+    // If the blocking variant would have blocked and that is what's wanted
+    if ( Cyg_Mqueue::WOULDBLOCK == err && !nonblocking && !badtimespec ) {
+        err = tabent->mq->put( msg_ptr, msg_len, msg_prio, true, 
+                               abs_ticks );
+    }
+
     switch (err) {
 
     case Cyg_Mqueue::INTR:
@@ -808,9 +817,17 @@ mq_timedreceive( mqd_t mqdes, char *msg_
     bool nonblocking = ((user->flags & O_NONBLOCK) == O_NONBLOCK);
     bool badtimespec = (abs_timeout->tv_nsec < 0) ||
         (abs_timeout->tv_nsec > 999999999l);
-    err = tabent->mq->get( msg_ptr, &msg_len, msg_prio,
-                           !nonblocking && !badtimespec,
-                           cyg_timespec_to_ticks(abs_timeout) );
+    cyg_tick_count abs_ticks = cyg_timespec_to_ticks(abs_timeout);
+
+    // We should never time out if there is something to read.  Simplest
+    // way to ensure this is to try the non-blocking get() first.
+    err = tabent->mq->get( msg_ptr, &msg_len, msg_prio, false, abs_ticks );
+
+    // If the blocking variant would have blocked and that is what's wanted
+    if ( Cyg_Mqueue::WOULDBLOCK == err && !nonblocking && !badtimespec ) {
+        err = tabent->mq->get( msg_ptr, &msg_len, msg_prio, true, abs_ticks );
+    }
+
     switch (err) {
 
     case Cyg_Mqueue::INTR:
--- a/packages/compat/posix/current/src/pthread.cxx
+++ b/packages/compat/posix/current/src/pthread.cxx
@@ -699,6 +699,13 @@ externC void pthread_exit (void *retval)
     
     pthread_info *self = pthread_self_info();
 
+    // Disable cancellation requests for this thread.  If cleanup
+    // handlers exist, they will generally be issuing system calls
+    // to clean up resources.  We want these system calls to run
+    // without cancelling, and we also want to prevent being
+    // re-cancelled.
+    pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
+
     // Call cancellation handlers. We eat up the buffers as we go in
     // case any of the routines calls pthread_exit() itself.
     while( self->cancelbuffer != NULL )