win32 : Get the state of an event object - c++

I'm creating 3 events with the following function:
HANDLE WINAPI CreateEvent(...);
I'm waiting on all (bWaitAll is set to TRUE) event objects or a timeout with:
DWORD WINAPI WaitForMultipleObjects(...);
The return value is:
WAIT_TIMEOUT
Is there an easy way to check each event to find the one(s) that was(where) not set?
As an example :
HANDLE evt1 = ....
HANDLE evt2 = ....
HANDLE evt3 = ....
HANDLE evts[3] = ....
DWORD ret = ::WaitForMultipleObjects(3, evts, TRUE, 10000);
After 10 sec :
'ret' is WAIT_TIMEOUT.
evt1 is set
evt2 is NOT set
evt3 is set
The return value tells me "The time-out interval elapsed and the conditions specified by the bWaitAll parameter are not satisfied.", but not which one were signaled and which one were not.
Thanks,

Yes, after WaitForMultipleObjects() returned call WaitForSingleObject() for each event specifying zero timeout.
It will return WAIT_TIMEOUT for events that are not signalled and WAIT_OBJECT_0 for signalled events. Don't forget to check for WAIT_FAILED.
Surely each event state might have been changed compared to the states they had at the moment WaitFormultipleObjects() returned.

OK. Total rewrite after having the question explained to me better in the comments.
So if I'm understanding this right now, you are calling WaitForMultipleObjects with bWaitAll set to true, and when you get WAIT_TIMEOUT back from it, want to figure out which objects are holding up the works.
In that case, I'm with sharptooth, sort of. You can call WaitForSingleObject with a 0 timeout for each object. The problem with doing this is that it has side-effects for some objects. For example, if you do this on a mutex and it succeeds, you not only know it wasn't the culprit, but you now own the mutex. If that isn't what you want, you'll have to know to immediately release it.
Any apporach you take is going to be subject to race conditions. Since you are outside of the "atomic" wait call, you could go through the process and discover that now they are all ready. You could get back a set of ready/unready that isn't what you actually had inside the wait call.
Ick.

None of this work, as WaitForSingleObject() will trigger an auto-reset event even when timeout is 0.
(Contrary to what MSDN says).

If your call returns WAIT_TIMEOUT it means that NONE of the objects you waited for was signalled..

Related

Replacement for Windows specific HANDLE, Event Creation and Sync API in case of Linux

I have a following set of codes specific to Windows,
//1: Declaring HANDLE
HANDLE *m_handle;
//2: Creating HANDLE instance
int m_Count = 4;
m_handle = new HANDLE[m_Count];
//3: Creating Events
for (int i = 0; i < m_Count ; i++)
{
m_handle [i] = CreateEvent(NULL, FALSE, FALSE, NULL);
}
//4: Synchronous API
DWORD dwEvent = WaitForMultipleObjects(m_Count, m_handle, TRUE, 30000);
//5: Closing the HANDLE
for (int i = 0; i < m_Count; i++)
{
CloseHandle(m_handle[i]);
}
How to write the same set of code in case of Linux?
The replacement for CreateEvent is eventfd, you probably want EFD_CLOEXEC and EFD_NONBLOCK flags. Don’t use the semaphore flag unless you know what you’re doing.
The replacement for WaitForMultipleObjects is poll, specify the POLLIN flag in the requested events. Just keep in mind the event is not being reset by poll, it will stay signalled. Read 8 bytes from the eventfd handle to reset. The functionality is identical to manual-reset events on Windows.
To signal an event, call write on the eventfd handle, passing the address of a local uint64_t variable with value 1.
To destroy events once you no longer need them, just call close.
Update: I’ve just noticed you’re passing bWaitAll=TRUE to WaitForMultipleObjects.
Unfortunately, Linux poll can’t quite do that. It returns when timeout is expired, or when at least 1 handle becomes signaled, whichever happens first.
Still, the workaround is not too hard. You can emulate bWaitAll by calling poll multiple times in a loop until all of the events are signaled. No need to rebuild the array of handles, you can set file handle to a negative value for the events which became signaled after poll returned. Note that multiple of them may become signaled at once, poll return value tells how many of them did. Also don't forget to decrease the timeout value.

How to make sure that WSASend() will send the data?

WSASend() will return immediately whether the data will be sent or not. But how to make sure that data will be sent, for example I have a button in my UI that will send "Hello World!" when pressed. Now I want to make sure that when the user click on this button the "Hello World!" will be sent at some point, but WSASend() could return WSAEWOULDBLOCK indicating that data will not be sent, so should I enclose WSASend() in a loop that does not exit until WSASend() returns 0 (success).
Note: I am using IOCP.
should I enclose WSASend() in a loop that does not exit until
WSASend() returns 0 (success)
Err.. NO!
Have the UI issue an overlapped WSASend request, complete with buffer/s and OVERLAPPED/s. If, by some miracle, it does actually return success immedately, (and I've never seen it), you're good.
If, (when:), it returns WSA_IO_PENDING, you can do nothing in your UI button-handler because GUI event-handlers cannot wait. Graphical UI's are state-machines - you must exit the button-handler and return to the message input queue in prompt manner. You can do some GUI stuff, if you want. Maybe disable the 'Send' button, or add some 'Message sent' text to a memo component. That's about it - you must then exit.
Some time later, the successful completion notification, (or failure notification), will get posted to the IOCP completion queue and a handler thread will get hold of it. Use PostMessage, QueueUserAPC or similar inter-thread comms mechanism to signal 'something', (eg. the buffer object used in the original WSASend), back to the UI thread so that it can take action/s on the returned result, eg. re-enabling the 'Send' button.
Yes, it can be seen as messy, but it is the only way you can do it that will work well.
Other approaches - polling loops, Application.DoEvents, timers etc are all horrible bodges.
Overlapped Socket I/O
If an overlapped operation completes immediately, WSASend returns a value of zero and the lpNumberOfBytesSent parameter is updated with the number of bytes sent. If the overlapped operation is successfully initiated and will complete later, WSASend returns SOCKET_ERROR and indicates error code WSA_IO_PENDING.
...
The error code WSA_IO_PENDING indicates that the overlapped operation has been successfully initiated and that completion will be indicated at a later time. Any other error code indicates that the overlapped operation was not successfully initiated and no completion indication will occur.
...
So as demonstrated in docs, you don't need to enclose in a loop, just check for a SOCKET_ERROR and if the last error is not equal to WSA_IO_PENDING, everything is fine:
rc = WSASend(AcceptSocket, &DataBuf, 1,
&SendBytes, 0, &SendOverlapped, NULL);
if ((rc == SOCKET_ERROR) &&
(WSA_IO_PENDING != (err = WSAGetLastError()))) {
printf("WSASend failed with error: %d\n", err);
break;
}

invoke methods in thread in c++

I have a class which reads from a message queue. Now this class has also got a thread inside it. Depending on the type of the msg in msg q, it needs to execute different functions inside that thread as the main thread in class always keeps on waiting on msg q. As soon as it reads a message from queue, it checks its type and calls appropriate method to be executed in thread and then it goes back to reading again(reading in while loop).
I am using boost message q and boost threads
How can I do this.
Its something like this:
while(!quit) {
try
{
ptime now(boost::posix_time::microsec_clock::universal_time());
ptime timeout = now + milliseconds(100);
if (mq.timed_receive(&msg, sizeof(msg), recvd_size, priority, timeout))
{
switch(msg.type)
{
case collect:
{
// need to call collect method in thread
}
break;
case query:
{
// need to call query method in thread
}
break;
and so on.
Can it be done?
If it can be done, then what happens in the case when thread is say executing collect method and main thread gets a query message and wants to call it.
Thanks in advance.
Messages arriving while the receiving thread is executing long operations will be stored for later (in the queue, waiting to be processed).
If the thread is done with its operation, it will come back and call the receive function again, and immediately get the first of the messages that arrived while it was not looking and can process it.
If the main thread needs the result of the message processing operation, it will block until the worker thread is done and delivers the result.
Make sure you do not do anything inside the worker thread that in turn waits on the main thread's actions, otherwise there is the risk of a deadlock.

WaitForSingleObject times out too fast

I have this piece of code in a secondary thread:
DWORD result = WaitForSingleObject(myhandle,10000);
if(result == WAIT_OBJECT_0){
AfxMessageBox(_T(...));
}
else if(result == WAIT_TIMEOUT){
AfxMessageBox(_T("Timeout"));
}
Sometimes, not always, the timeout will get called almost as soon as the WaitForSingleObject is called (not even 1s delay).
Am I doing something wrong ? Any suggestions for more stable alternatives ?
EDIT:
myhandle is created inside a class constructor as:
myhandle = CreateEvent(NULL,FALSE,FALSE,_T("myhandle"));
it would get called by another function:
SetEvent(myhandle);
The point is it works when I do the SetEvent, the problem is that it sometimes times out as soon as the WaitForSingleObject is called, even though it should wait 10s.
Do you really need/want a named event? Typically this is only required for inter-process concurrency control.
If you have multiple instances of this class they will all use the same event - see the docs for CreateEvent about calling for a named object that already exists.
It may be that all you need to do is remove the name here. This allows each class instance to have its own Event object and behaviour should be more predictable.
WaitForSingleObject will not wait the whole 10 seconds. It will wait for the first of:
The timeout value is elapsed
The event is signaled
The handle becomes invalid (closed in another thread)
If the event is set when you call WaitForSingleObject, condition #2 is true from the start and WaitForSingleObject returns immediatly.
If you want to always wait 10 seconds, you should use code like this :
//Always wait 10 seconds
Sleep(10000);
//Test the event without waiting
if(WaitForSingleObject(myhandle, 0) == WAIT_OBJECT_0) {
AfxMessageBox(_T("Event was set in the last 10 secondes"));
} else {
AfxMessageBox(_T("Timeout"));
}
Took awhile but the problem actually was that the program sometimes did multiple calls to WaitForSingleObject. So it's a previous call that is timing out.
Solution is to use WaitForMultipleObjects and set a cancelling event in the case it is known that the first event won't be set, so the timer is cancelled before is it re-invoked.

Threading in a DLL where the DLL must return before child thread finishes

I am working on writing a wrapper DLL to interface a communication DLL for a yokogawa WT1600 power meter, to a PC based automation package. I got the communication part to work but I need to thread it so that a 50ms scan time of the automation package can be maintained. (The Extended Function Block (EFB) Call will block the scan until it returns)
These are the steps I need to do.
Call EFB
EFB creates a thread to perform communication setup (takes about 200ms to do)
EFB returns EFB_BUSY while the thread is doing the work
3a. (automation program continues scanning until it comes back to the EFB call)
Call EFB passing in that it returned busy on the last call
EFB checks if the thread has returned
If the thread returned Then the EFB returns success, Else return EFB_BUSY
repeat 3a-6 until efb returns success
So my problem is, how do I create a thread that exists past the life of the function that called it? And how do I get that thread return value when I call back into the DLL?
EDIT #1
HeavyFunction::HeavyFunction^ hf; //HeavyFunction is a class that has a time consuming function in it
ThreadStart^ efbThreadDelegate;
Thread^ efbThread;
if( pEfbData->nBlockingRecall != DOEFB_BUSY ) {
hf = gcnew HeavyFunction::HeavyFunction;
hf->iiStart = (int)(pEfbData->uParams[0].dw);
hf->iiEnd = (int)(pEfbData->uParams[1].dw);
efbThreadDelegate = gcnew ThreadStart( hf, &HeavyFunction::HeavyFunction::iGetPrime );
efbThread = gcnew Thread( efbThreadDelegate );
efbThread->Start();
return DOEFB_BUSY;
}else if ( efbThread->IsAlive ) {
return DOEFB_BUSY;
}else {
uRetValue->dw = hf->iReturn;
return 0;
}
Will efbThread still have the same thread handle upon a subsequent call?
EDIT #2
I got it to work by creating a global HANDLE for a Mutex and a thread. Initializing the mutex in the init entry point (done upon dll loading) and creating the thread in the main function when a call is actually made to the dll.
I used the sample code from MSDN: Creating Threads as my model.
Any thread created (whether in a DLL or elsewhere) will not stop spontaneously. In particular, the function that created the thread may return. The new thread would still run even if the creator thread exited. That is, assuming it didn't hit the end of its entry function.
Windows threads return a DWORD when ready. To peek, call WaitForSingleObject on the thread handle with a 0 second timeout, and it that succeeds, call GetExitCodeThread .
I don't understand your whole "EFB" thing, neither what it is nor what it does, though. If it is doing funny things to normal Windows threads, all bets are off.