dotgnu-pnet-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Dotgnu-pnet-commits] CVS: pnet/support wakeup.c,1.4,1.5


From: Thong Nguyen <address@hidden>
Subject: [Dotgnu-pnet-commits] CVS: pnet/support wakeup.c,1.4,1.5
Date: Sat, 12 Jul 2003 02:36:15 -0400

Update of /cvsroot/dotgnu-pnet/pnet/support
In directory subversions:/tmp/cvs-serv3086/support

Modified Files:
        wakeup.c 
Log Message:
Fixed race condition in ILWakeupWait


Index: wakeup.c
===================================================================
RCS file: /cvsroot/dotgnu-pnet/pnet/support/wakeup.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -C2 -r1.4 -r1.5
*** wakeup.c    7 Jul 2003 01:58:32 -0000       1.4
--- wakeup.c    12 Jul 2003 06:36:12 -0000      1.5
***************
*** 4,7 ****
--- 4,9 ----
   * Copyright (C) 2002  Southern Storm Software, Pty Ltd.
   *
+  * Contributions fom Thong Nguyen (address@hidden)
+  *
   * This program is free software; you can redistribute it and/or modify
   * it under the terms of the GNU General Public License as published by
***************
*** 97,133 ****
                /* Give up the lock and wait for someone to signal us */
  
!               /* But first make sure someone hasn't already signalled us
!                  between the time we registered the wakeup and the time
!                  we called ILWakeupWait (if a signal was sent we would
!                  have missed it). */
!                  
!               if(wakeup->count >= wakeup->limit
!                       || _ILCondVarTimedWait(&(wakeup->condition), 
&(wakeup->lock), ms))
                {
!                       if(wakeup->interrupted)
                        {
!                               /* The wakeup object was interrupted */
!                               wakeup->interrupted = 0;
!                               result = -1;
                        }
                        else
                        {
!                               /* All signals that we were expecting have 
arrived */
!                               if(object)
                                {
!                                       /* Return the last object that was 
signalled */
!                                       *object = wakeup->object;
                                }
!                               result = 1;
                        }
                }
!               else
!               {
!                       /* The wakeup object timed out.  We still check for 
interrupt
!                          because we may have been interrupted just after 
timeout,
!                          but before this thread was re-awoken */
!                       result = (wakeup->interrupted ? -1 : 0);
!                       wakeup->interrupted = 0;
!               }
                wakeup->count = 0;
                wakeup->limit = 0;
--- 99,175 ----
                /* Give up the lock and wait for someone to signal us */
  
!               /*
!                *      Two subtle races to consider:
!                *
!                * 1: Signal arrives between adding a wakeup to the queue and 
waiting on the wakeup.
!                *     The signal will get missed and the thread will halt 
indefinitely.
!                *     The while loop predicate allows the thread to exit 
successfully if we missed 
!                *     the signal.
!                *
!                * 2: We get here, notice the wakeup->count < wakeup->limit, 
don't bother waiting
!                *     on the signal.  No context switch is made, we reset and 
register our wakeup again
!                *     and get the signal that was intended for the last time 
we registered the wakeup.
!                *     The thread will wakeup when it shouldn't.
!                *     The "continue" in the while loop makes us keep waiting
!                */
! 
!               while (wakeup->count < wakeup->limit)
                {
!                       if (_ILCondVarTimedWait(&(wakeup->condition), 
&(wakeup->lock), ms))
                        {
!                               if (wakeup->interrupted)
!                               {
!                                       wakeup->interrupted = 0;
! 
!                                       result = -1;
! 
!                                       break;
!                               }
!                               else
!                               {
!                                       if (wakeup->count < wakeup->limit)
!                                       {
!                                               /*
!                                                * This signal was from a 
previous wakeup registration.
!                                                *
!                                                * No need to adjust "ms" 
because the time difference will be very
!                                                * small.
!                                                */
!                                                  
!                                               continue;
!                                       }
! 
!                                       /* All signals that we were expecting 
have arrived */
!                                       if(object)
!                                       {
!                                               /* Return the last object that 
was signalled */
!                                               *object = wakeup->object;
!                                       }
!                                       result = 1;
! 
!                                       break;
!                               }
                        }
                        else
                        {
!                               /* The wakeup object timed out.  We still check 
for interrupt
!                               because we may have been interrupted just after 
timeout,
!                               but before this thread was re-awoken */
! 
!                               if (wakeup->interrupted)
!                               {
!                                       result = -1;
!                                       wakeup->interrupted = 0;
!                               }
!                               else
                                {
!                                       /* Timed out */
!                                       result = 0;
                                }
!                               
!                               break;
                        }
                }
! 
                wakeup->count = 0;
                wakeup->limit = 0;





reply via email to

[Prev in Thread] Current Thread [Next in Thread]