-1

Why is HANDLE event object(synchronization object which is created by CreateEvent function) in winapi assumed to be valid in thread function?

From multithreading example to microsoft docs code examples, this event object is passed to WaitForSingleObject function without any protection.

I've been doing the same. And today, I just reached to the thought that how can I deal with this "branch" safe, in such a sense like branch coverage in code perspective.

In the strict sense, this event object is shared along multiple threads, at least in the thread which calls SetEvent and in the thread which Calls WaitForSingleObject.

Therefore, it has to be classified as a type of shared resource. Then, all shared resources must be protected by "lock", such as mutex or critical section.

Also, it is possible to deliberately call CloseHandle after SetEvent while thread is alive, which will lead to passing closed event handle to WaitForSingleObject in thread function. (maybe the event object won't be deleted due to deferred deletion)

Acquiring lock and calling WaitForSingleObject in thread function, and trying to acquire lock in other thread in order to call SetEvent would definitely lead to deadlock.

[EDIT]

Maybe I misled my point by mentioning "assumed" and particular code example. I wonder how to do thread safe validity check for HANDLE event object, treating HANDLE as variable.

YoonSeok OH
  • 647
  • 2
  • 7
  • 15
  • 2
    That handle is created before a thread creation and closed after threads exit, thus it is const semantically between creation and exit and there is no data race. – 273K May 07 '22 at 15:58
  • 1
    *"this event object is passed to WaitForSingleObject function without any protection"* - No, it isn't. What's passed is a **value** suitable for identifying the object. That's what a handle is. That out of the way, what is your actual question? – IInspectable May 07 '22 at 16:10
  • 1
    just like you don't protect `std::mutex::lock()` – apple apple May 07 '22 at 16:40
  • Thank you for your comment 273K. Yes, the handle is created before a thread creation and close after threads exit in the code examples. I know that, but thread function don't. As far as scenario such as deliberately calling CloseHandle is possible, which means case is open, I wonder how the event object handle can be thread safely checked. Maybe I should change my question. – YoonSeok OH May 08 '22 at 14:53
  • Thank you for your comment IInspectable. My point is no matter what type of data is, HANDLE or value or pointer, as far as they are still shared data. For example, if one thread reads HANDLE (value) and one other thread writes HANDLE such as reinterpret_cast(0x12345678), this is just an example. – YoonSeok OH May 08 '22 at 15:07

1 Answers1

0

According to Synchronizing Execution of Multiple Threads, There are a number of objects whose handles can be used to synchronize multiple threads. These objects include:

  • Console input buffers
  • Events
  • Mutexes
  • Processes
  • Semaphores
  • Threads
  • Timers

The state of each of these objects is either signaled or not signaled.(atomic)

For handle concerned, WaitForSingleObject function say If this handle is closed while the wait is still pending, the function's behavior is undefined.
For an invalid handle, It's programmer's responsibility to troubleshoot where the handle becomes invalid(BUG).

YangXiaoPo-MSFT
  • 1,589
  • 1
  • 4
  • 22