I can't figure out how to get this to work. I have 3 events in a function that triggers 3 different function.
First I create the events
CreateEventsAndThreads proc
mov edi,offset hEvents
invoke CreateEvent,0,TRUE,FALSE,0
mov hEvent1,eax
mov dword ptr [edi],eax
invoke CreateEvent,0,TRUE,FALSE,0
mov hEvent2,eax
mov dword ptr [edi+4],eax
invoke CreateEvent,0,TRUE,FALSE,0
mov hEvent3,eax
mov dword ptr [edi+8],eax
invoke CreateThread,0,0,offset ThreadFunction,hEvent1,0,addr ThreadID
invoke CreateThread,0,0,offset ThreadFunction,hEvent2,0,addr ThreadID
invoke CreateThread,0,0,offset ThreadFunction,hEvent3,0,addr ThreadID
ret
CreateEventsAndThreads endp
The ThreadFunction is like this
ThreadFunction proc lParam:dword
invoke WaitForMultipleObjects,3,offset hEvents,TRUE,INFINITE
.if eax==0
;code
invoke ResetEvent,hEvent1
.elseif eax==1
;code
invoke ResetEvent,hEvent1
.elseif eax==2
;code
invoke ResetEvent,hEvent1
.endif
ret
ThreadFunction endp
And the function that will trigger the events
TriggerFunction proc
;code
invoke SetEvent,hEvent1
;code
invoke SetEvent,hEvent2
;code
invoke SetEvent,hEvent3
ret
TriggerFunction endp
This is initiation code
invoke CreateEventsAndThreads
invoke TriggerFunction
The Triggerfunction does what it should do but the events are not triggered.
I do something wrong in principle?
It's not clear to me what you expect the code to do, so I have no idea what, or if, you did wrong. You have the treads running immediately after they are created, all executing the same procedure, you have WaitForMultipleObjects waiting for all of the objects to be signaled, and there is no code to indicate what is happening. As the code currently is, and running on a single core, the thread procedure gets called three times, and WaitForMultipleObjects returns once, in the first thread, and the other two threads are left waiting.
Thanks for your answer.
The triggerfunction is working and in three places values are created that are needed in three different functions. I want this functions to run immediately after the values are created.
ThreadFunction proc lParam:dword
invoke WaitForMultipleObjects,3,offset hEvents,FALSE,INFINITE
.if eax==WAIT_OBJECT_0
invoke Function1,value1
invoke ResetEvent,hEvent1
.elseif eax==1
invoke Function2,value2
invoke ResetEvent,hEvent2
.elseif eax==2
invoke Function2,value2
invoke ResetEvent,hEvent3
.endif
ret
ThreadFunction endp
I have changed the lfWaitAll to false and now WaitForMultipleObjects is signaled. But at every time return value is WAIT_OBJECT_0.
If I write
.if eax==WAIT_OBJECT_0 && lParam==hEvent[0]
then it work as I like it. But I don't think it acts like MSDN writes.
Quote
If bWaitAll is TRUE, the return value indicates that the state of all specified objects is signaled.
If bWaitAll is FALSE, the return value minus WAIT_OBJECT_0 indicates the lpHandles array index of the object that satisfied the wait. If more than one object became signalled during the call, this is the array index of the signalled object with the smallest index value of all the signalled objects.
A return value of WAIT_OBJECT_0 (= 0) indicates that the first event object in the array caused the function to return, because it was the first one set.
Yes, but when Event2 is set return value is still WAIT_OBJECT_0. As I read MSDN i should be 1. Isn't that so?
If I comment out invoke SetEvent,hEvent1, then the return value is 1.
If I also comment out SetEvent,hEvent2, then the return value is 2.
It will not work as I expected. I attach a simple project. The triggerfunction does what it should but not the events.
The Win32 API functions as described. As you don't have each thread watching it's own event it gets reflected in all three, but then again the implementation is asinine.
The attached trivial C/EXE example demonstrates pressing key 1,2,3 to trigger the events, ESCape to quit.
C:\MASM\EventAndThreads>testwait
Thread Started 000007E8
Press 1,2,3 or Q to quit
Thread Started 000007DC
Thread Started 000007F4
1
Event 1
Event 1
Event 1
2
Event 2
Event 2
Event 2
3
Event 3
Event 3
Event 3
2
Event 2
Event 2
Event 2
I think I missunderstod how to use WaitForMultipleObjects. I thought the function returns for each event if the fWaitAll is false no matter in which order the events occur.
Reading MSDN more carefully i think the function return only once and only for the event that occurs first.
Is this a correct understanding?
It will either return once *all* have been triggered, or return once *any* of them have, with the return value being the array index of whichever event happened.
-r
As redskull indicates it's an ALL or ONE function. In the ALL case the order is inconsequential.
Why do you need to use WaitForMultipleObjects, when each thread should be waiting for it's own event and call it's own processing routine? This could be better implemented by using a) a single thread process subroutine started with three different thread contexts (Event, Processing Routine, etc), or b) starting three threads, each with it's own unique thread process subroutine.
A freestanding ThreadProcess would look this is C pseudo code
DWORD ThreadProcess(LPVOID lpParameter)
{
CONTEXT *Context = (CONTEXT *)lpParameter;
DWORD Returned;
while(1)
{
Returned = WaitOnSingleObject(Context->hEvent, INFINITE);
ResetEvent(Context->hEvent);
Context->Handler(Context, Param1, Param2, Param3);
}
return(1);
}
As I wrote in my previous post i missunderstod MSDN. My english is not so good.
As a matter of fact I need both WaitForSingleObject and WaitForMultipleObjects to wath when certain values are available to process. Thera are a lot of data to process. The project I posted was only an atempt to describe what I wanted to do.
After the understanding of how these apis works I can continue with my project