On Wed, 8 Sep 2021 13:11:41 +0900 Takashi Yano wrote: > On Wed, 8 Sep 2021 09:07:48 +0900 > Takashi Yano wrote: > > On Tue, 7 Sep 2021 19:50:23 +0900 > > Takashi Yano wrote: > > > > > @@ -796,7 +792,8 @@ pipe_cleanup (select_record *, select_stuff *stuff) > > > pi->stop_thread = true; > > > SetEvent (pi->bye); > > ~~~~~~~~~~~~~~~~~~~ > > This is not correct. SetEvent() wakes-up one of thread_pipe()s, > > but it may be other thread than one which should be stopped. > > > > > pi->thread->detach (); > > > - CloseHandle (pi->bye); > > > + if (me->fh->get_select_evt () == NULL) > > > + CloseHandle (pi->bye); > > > } > > > delete pi; > > > stuff->device_specific_pipe = NULL; > > > > I think it also should be > > > + for (ULONG i = 0; i < get_obj_handle_count (select_evt); i++) > > > + SetEvent (select_evt); > > > > Actually I want to use PulseEvent() here if it is not **UNRELIABLE**. > > https://docs.microsoft.com/en-us/windows-hardware/drivers/devtest/28648-pulseevent-is-an-unreliable-function > > > > Does using semaphore object instead of event, and releasing > > resources equal to the number of handles make sense? > > No it does not. One thread may consume semaphore multiple times.... I wrote a simple test program which counts wake-up 1000 times in 100 threads, and confirmed that semaphore method works as expected as well as PulseEvent(). All 100000 (100*1000) wake-up were counted without miscount. Therefore, patch attached should work. -- Takashi Yano