diff --git a/rtl/unix/cthreads.pp b/rtl/unix/cthreads.pp index f77bf98790..d9c7f63521 100644 --- a/rtl/unix/cthreads.pp +++ b/rtl/unix/cthreads.pp @@ -71,6 +71,7 @@ Type PINTRTLEvent = ^TINTRTLEvent; TINTRTLEvent = record condvar: pthread_cond_t; mutex: pthread_mutex_t; + IsSet: boolean; end; {***************************************************************************** @@ -737,6 +738,7 @@ begin new(p); pthread_cond_init(@p^.condvar, nil); pthread_mutex_init(@p^.mutex, nil); + p^.IsSet:= false; result:=PRTLEVENT(p); end; @@ -757,15 +759,21 @@ var p:pintrtlevent; 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); @@ -781,11 +789,11 @@ var p:pintrtlevent; 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; @@ -803,9 +811,14 @@ procedure intRTLEventWaitForTimeout(AEvent: PRTLEvent;timeout : longint); 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;