News:

MASM32 SDK Description, downloads and other helpful links
MASM32.com New Forum Link
masmforum WebSite

How do I handle multiple events and threads?

Started by minor28, August 21, 2010, 10:09:05 AM

Previous topic - Next topic

minor28

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?

MichaelW

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.
eschew obfuscation

minor28

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.

minor28

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.

MichaelW

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.
eschew obfuscation

minor28

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?

MichaelW

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.
eschew obfuscation

minor28

It will not work as I expected. I attach a simple project. The triggerfunction does what it should but not the events.


clive

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
It could be a random act of randomness. Those happen a lot as well.

minor28

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?

redskull

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
Strange women, lying in ponds, distributing swords, is no basis for a system of government

clive

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);
}
It could be a random act of randomness. Those happen a lot as well.

minor28

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