[fpc-devel] Exact details for RTLeventWaitFor and related ?
Kirinn
kirinn at mooncore.eu
Sat Aug 22 03:50:09 CEST 2020
When I researched synchronisation behavior and wrote the wiki page
"Threads", I found that RTL events behave like this:
- When the event is set, a single waiting thread is released (in FIFO
order), and the event is automatically immediately reset.
- The event can only be in a set or unset state; multiple sets do not
stack. Even if the event is set twice or ten times, a single WaitFor or
Reset will change it to unset. This is a likely cause for deadlocks.
- Because the event is automatically reset when a waiting thread is
released, calling ResetEvent is generally unnecessary.
For set/reset counting we'd need a semaphore instead of an RTL event,
but I don't think we have an actively supported semaphore implementation
at this time.
Caveat: The above was true for FPC 3.0.4 on Windows and Linux. 3.2.0 or
trunk may have changed something, and I can't vouch for other platforms.
~Kirinn
On 8/22/20 1:44 AM, Martin via fpc-devel wrote:
> I am tracing a race condition in lazCollections TLazThreadedQueue
> on win-64
>
> What is supposed to happen in the following case:
>
> 2 or more threads are waiting on the some event
> RTLeventWaitFor(UniqueEvent)
>
> 1 thread sets it
> RTLeventSetEvent(UniqueEvent)
>
> I expect that wakes up exactly ONE thread (never mind wich)?
> Or ALL?
>
> If no one resets the event (NO call to RTLeventResetEvent), then that
> does not change anything? It is still just the one thread that got
> woken up?
>
> Thanks for any feedback
> Martin
>
>
> p.s.
> Background
>
> TLazThreadedQueue.PopItem works like this
>
> EnterCritical
> If item avail then return item
> ExitCritical
> // race condition between those lines.
> RTLeventWaitFor(itemAdded)
> EnterCritical
> If item avail then return
> ExitCritical
>
> If 2 or more reading (popping) threads are both at the indicated
> location,
> and if during this time 2 or more items are added
> then there is a problem (I believe)
>
> adding (pushing) an item does
> RTLeventSet(itemAdded)
> adding 2 items (with no pop in between) calls Set twice
> =>
> https://lazarus-ccr.sourceforge.io/docs/rtl/system/rtleventsetevent.html
> It is unclear if the 2nd RTLeventSet has any effect ?
>
>
> According to my tests:
> - I "sleep()" 2 listeners at the critical line, so they both will
> WaitFor after the sleep
> - while they sleep I add 2 items (2 calls to RTLeventSet, no one
> listening yet)
> - Both start RTLeventWaitFor
> => only one listener wakes up.
> Is that the expected behaviour?
>
> _______________________________________________
> fpc-devel maillist - fpc-devel at lists.freepascal.org
> https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel
More information about the fpc-devel
mailing list