I had problems with a threaded app under Linux which hung because one
thread would sometimes call RTLSetEvent before the other called
RTLEventStartWait.  The attached patch for the 2.1.1 branch revision
5606 fixes the problem.
Index: cthreads.pp
===================================================================
--- cthreads.pp	(revision 5606)
+++ cthreads.pp	(working copy)
@@ -53,6 +53,7 @@
       TINTRTLEvent = record
         condvar: pthread_cond_t;
         mutex: pthread_mutex_t;
+        IsSet: boolean;
        end;
 
 {*****************************************************************************
@@ -512,6 +513,7 @@
   new(p);
   pthread_cond_init(@p^.condvar, nil);
   pthread_mutex_init(@p^.mutex, nil);
+  p^.IsSet:= false;
   result:=PRTLEVENT(p);
 end;
 
@@ -532,17 +534,23 @@
 begin
   p:=pintrtlevent(aevent);
   pthread_mutex_lock(@p^.mutex);
+  p^.IsSet:= true;
   pthread_cond_signal(@p^.condvar);
   pthread_mutex_unlock(@p^.mutex);
 end;
 
 
 procedure intRTLEventResetEvent(AEvent: PRTLEvent);
-  begin
-    { events before startwait are ignored unix }
-  end;
+var p:pintrtlevent;
 
+begin
+  p:=pintrtlevent(aevent);
+  pthread_mutex_lock(@p^.mutex);
+  p^.IsSet:= false;
+  pthread_mutex_unlock(@p^.mutex);
+end;
 
+
 procedure intRTLEventStartWait(AEvent: PRTLEvent);
 var p:pintrtlevent;
 
@@ -556,11 +564,11 @@
 
 begin
   p:=pintrtlevent(aevent);
-  pthread_cond_wait(@p^.condvar, @p^.mutex);
+  while not p^.IsSet do pthread_cond_wait(@p^.condvar, @p^.mutex);
+  p^.IsSet:=false;
   pthread_mutex_unlock(@p^.mutex);
 end;
 
-
 procedure intRTLEventWaitForTimeout(AEvent: PRTLEvent;timeout : longint);
   var
     p : pintrtlevent;
@@ -578,11 +586,14 @@
       inc(timespec.tv_sec);
       dec(timespec.tv_nsec, 1000000000);
     end;
-    errres:=pthread_cond_timedwait(@p^.condvar, @p^.mutex, @timespec);
-    if (errres=0) or (errres=ESysETIMEDOUT) then
-      pthread_mutex_unlock(@p^.mutex);
+    errres:=0;
+    while (not p^.IsSet) and (errres <> ESysETIMEDOUT) do begin
+       errres:=pthread_cond_timedwait(@p^.condvar, @p^.mutex, @timespec);
+    end;
+    p^.IsSet:= false;
+    pthread_mutex_unlock(@p^.mutex);
   end;
-  
+
 function cSemaphoreInit: Pointer;
 var
   s: PSemaphore;
_______________________________________________
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
http://lists.freepascal.org/mailman/listinfo/fpc-devel

Reply via email to