How to check event object's state without actually changing it? - winapi

The problem is that the WaitForMultipleObjects(Ex) returns just smallest index of all the signalled objects in an array. I would like to know what exactly event objects (created using CreateEvent) are in signalled (or non-signalled) state.
I think it is not possible but decided to ask just to make sure I'm not missing anything =)

For each object whose state you want to test, call WaitForSingleObject with a timeout of zero. If it returns WAIT_OBJECT_0, then the object is signaled. Otherwise, it's not.
Unless you have an auto-reset event, waiting for an object to become signaled does not alter its state.
Keep in mind that the state you detect with WaitForSingleObject isn't necessarily the same state the object had when WaitForMultipleObjects returned. More objects might have become signaled in the meantime, and other objects might have become non-signaled.

Related

When (how quickly) is a golang child function cancelled when cancelFunc() is called?

I want to access Redis and do a GET on two machines simultaneously. I'll use the first result I get and cancel the other call.
What I'm wondering is whether cancelFunc() breaks a go function immediately or whether it will wait for a specific event to happen before it notices the signal. The documentation just says:
Calling the CancelFunc cancels the child and its children, removes the parent's reference to the child, and stops any associated timers.
That doesn't say whether it happens immediately or whether a special cancellation point needs to be reached.
Any documentation I missed about that particular point?
Canceling a context simply closes its Done channel, it doesn't "kill" a goroutine or anything like that. Code that executes under the context has to do a select to notice the closure of the Done channel and abandon whatever work it's doing.
However in many cases this work is already done for you. If the redis client method you're using to make requests accepts a context, then it's safe to assume that if that context is canceled, the client will handle the cancellation and the method will immediately return an error of context.Canceled — all you need to do is handle that error by quitting what you're doing.

Does closing an event object cause threads waiting on that object to wake up?

Suppose I have a Windows event object, e.g. from calling CreateEvent.
Thread A is blocked in WaitForSingleObject(event_handle).
Thread B calls CloseHandle(event_handle).
Question 1: What happens to thread A?
Question 2: Does it make a difference if Thread A is blocked in WaitForMultipleObjects? What does WaitForMultipleObjects return?
From experimentation, it seems that WaitForSingleObject does not wake up if the handle is closed, i.e. thread A keeps waiting. I haven't checked, but I assume WaitForMultipleObjects is the same.
I suspect what's going on is that event objects inside the kernel are reference counted. CloseHandle drops a reference, but it doesn't necessarily destroy the underlying object. (For example, if multiple processes hold handles to the same object, the object isn't destroyed until all of the processes call CloseHandle.) And WaitForSingleObject also takes a reference to the object it waits for. Of course, I don't have the Windows source code so I can't confirm this for certain.

Coalescing GCD file system events

I have a class that implements a file-monitoring service to detect when a file I am interested in has been changed by something other than my application. I use the standard technique of opening the file (with the O_EVTONLY flag) and binding the file descriptor to a Grand Central Dispatch source of type DISPATCH_SOURCE_TYPE_VNODE. When I get an event, I notify my main thread with NSNotificationCenter's postNotificationName:object:userInfo: which calls an observer in my app delegate. So far so good. It works great. But, in general, if the triggering event is an attributes change (i.e. the DISPATCH_VNODE_ATTRIB flag is set on return from dispatch_source_get_data()) then I usually get two closely-spaced events. The behaviour is easily exhibited if I touch(1) the object I am monitoring. I hypothesise this is due to the file's mtime and atime being set non-atomically although I can't verify this. This can lead to spurious notifications being sent to my observer and this raises the possibility of race conditions etc.
What is the best way of dealing with this? I thought of storing a timestamp for the last event received and only sending a notification if the current event is later than this timestamp by some amount (a few tens of milliseconds?) Does this sound like a reasonable solution?
You can't ever escape the "race condition" in this situation, because the notification of your GCD event source in your process is not synchronous with the other process's modification of the underlying file. So, no matter what, you must always be tolerant of the possibility that the change you're being notified for could already be "gone."
As for coalescing, do whatever makes sense for your app. There are two obvious strategies. You can act immediately on a received event, and then drop subsequent events received in some time window on the floor, or you can delay every event for some time period during which you will drop other events for the same file on the floor. It really just depends on what's more important, acting quickly, or having a higher likelihood of a quiescent state (knowing that you can never be sure things are quiescent.)
The only thing I would add is to suggest that you do all your coalescence before dispatching anything to the main thread. The main thread has things like tracking loops, etc that will make it harder to get time-based coalescing right in certain cases.

Does <do-status> with level "retry" block any other event from being processed?

I have a NetIQ (Novell) IDM 4.0.1 driver. In a policy I have a <do-status> rule with level retry.
Does this retry block any other event from being processed?
From the logic of the application the event for (A) can not be processed until the object (B) is associated by the very same driver. Therefore I have added the retry rule on (A). However, it seems that the event for (B) is blocked when the event for (A) is waiting for being retried. If I use veto instead of retry for (A) then the event for (B) is processed regulary.
Is the behaviour specified somewhere?
This takes the top event in the queue, and retries it every 'interval' (which is defined in an Engine Control Value, defaults to 30 seconds).
So yes, it blocks all following events until it completes and stops being a retry.
What you could do is much simpler. In the Input Transform policy set, look for the operation add-association since that is when the object is successfully added to the connected system.
Then do your rule B stuff.
Unless you mean two different objects A and B, that are otherwise unrelated. If so, would let object A logic go through, and when you see object B come through then do the work on object A that is needed.

What's the proper way to use coroutines for event handling?

I'm trying to figure out how to handle events using coroutines (in Lua). I see that a common way of doing it seems to be creating wrapper functions that yield the current coroutine and then resume it when the thing you're waiting for has occured. That seems like a nice solution, but what about these problems? :
How do you wait for multiple events at the same time, and branch depending on which one comes first? Or should the program be redesigned to avoid such situations?
How to cancel the waiting after a certain period? The event loop can have timeout parameters in its socket send/receive wrappers, but what about custom events?
How do you trigger the coroutine to change its state from outside? For example, I would want a function that when called, would cause the coroutine to jump to a different step, or start waiting for a different event.
EDIT:
Currently I have a system where I register a coroutine with an event, and the coroutine gets resumed with the event name and info as parameters every time the event occurs. With this system, 1 and 2 are not issues, and 3 can solved by having the coro expect a special event name that makes it jump to the different step, and resuming it with that name as an arg. Also custom objects can have methods to register event handlers the same way.
I just wonder if this is considered the right way to use coroutines for event handling. For example, if I have a read event and a timer event (as a timeout for the read), and the read event happens first, I have to manually cancel the timer. It just doesn't seem to fit the sequential nature or handling events with coroutines.
How do you wait for multiple events at the same time, and branch depending on which one comes first?
If you need to use coroutines for this, rather than just a Lua function that you register (for example, if you have a function that does stuff, waits for an event, then does more stuff), then this is pretty simple. coroutine.yield will return all of the values passed to coroutine.resume when the coroutine is resumed.
So just pass the event, and let the script decide for itself if that's the one it's waiting for or not. Indeed, you could build a simple function to do this:
function WaitForEvents(...)
local events = {...}
assert(#... ~= 0, "You must pass at least one parameter")
do
RegisterForAnyEvent(coroutine.running()) --Registers the coroutine with the system, so that it will be resumed when an event is fired.
local event = coroutine.yield()
for i, testEvt in ipairs(events) do
if(event == testEvt) then
return
end
end
until(false)
end
This function will continue to yield until one of the events it is given has been fired. The loop assumes that RegisterForAnyEvent is temporary, registering the function for just one event, so you need to re-register every time an event is fired.
How to cancel the waiting after a certain period?
Put a counter in the above loop, and leave after a certain period of time. I'll leave that as an exercise for the reader; it all depends on how your application measures time.
How do you trigger the coroutine to change its state from outside?
You cannot magic a Lua function into a different "state". You can only call functions and have them return results. So if you want to skip around within some process, you must write your Lua function system to be able to be skippable.
How you do that is up to you. You could have each set of non-waiting commands be a separate Lua function. Or you could just design your wait states to be able to skip ahead. Or whatever.

Resources