On 22/08/2020 03:50, Kirinn via fpc-devel wrote:
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.
I can confirm this on Windows.

- If I set the event, and then 2 threads enter WaitFor => only 1 thread resumes - If I set the event, and then 1 threads enter WaitFor, resumes and enters WaitFor a 2nd time => then 2nd time does NOT resume - If 2 threads enter WaitFor, and I set the event (once) while they are waiting => only 1 thread resumes

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.
I can solve the issue at hand without a semaphore.
I just needed to know.


On 22/08/2020 12:50, Sven Barth wrote:
On Windows these are direct calls to the WinAPI functions WaitForSingleObject and SetEvent (and the created event is an Auto Reset Event), so you should probably take a look at the MSDN documentation for them...
Indeed....

https://docs.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-setevent
SetEvent
The state of a manual-reset event object remains signaled until it is set explicitly to the nonsignaled state by the ResetEvent <https://docs.microsoft.com/en-us/windows/desktop/api/synchapi/nf-synchapi-resetevent> function. Any number of waiting threads, or threads that subsequently begin wait operations for the specified event object by calling one of the wait functions <https://docs.microsoft.com/en-us/windows/desktop/Sync/wait-functions>, can be released while the object's state is signaled.
https://docs.microsoft.com/en-us/windows/win32/api/synchapi/nf-synchapi-waitforsingleobject
WaitForSingleObject
The function modifies the state of some types of synchronization objects. Modification occurs only for the object whose signaled state caused the function to return. For example, the count of a semaphore object is decreased by one.

On current Win10, it definitely only wakes one thread once.
WaitForSingleObject gives semaphores as example, but does not say which other objects it may modify.

In any case, I can safely RTLEventReset the event in whatever thread wakes first, and then immediately RTLEventSet it again (if needed).

That should be safe. It should also work, for any OS, on which multiple threads where released. (The last one will Reset, but not Set it => so it will be cleared when all is done / in the use-case I am looking at)

Thanks to everyone for the detailed responses.
Martin
_______________________________________________
fpc-devel maillist  -  fpc-devel@lists.freepascal.org
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel

Reply via email to