I want to send a message to the UI thread using PostMessage(), and I need to guarantee that the message is actually sent. However, PostMessage() can fail, so how should I handle the case when it fails, should I place it in a while loop that does not exit until PostMessage() returns success?
Since you can't guarantee delivery, as you indicate yourself, you need to instead decide how bad failure is. It sounds pretty critical, so I'd simply terminate the app. What else could you do?
Related
If FILE_SKIP_COMPLETION_PORT_ON_SUCCESS is not enabled, then even if the operation completes immediately with success, I still get a completion notification on the completion port. I'd like to know if this is the case if it completes immediately with errors as well.
I process completions with handlers that I store as std::function in an extended OVERLAPPED struct, and are executed by the thread pool that is looping on the completion port. Having FILE_SKIP_COMPLETION_PORT_ON_SUCCESS disabled means that I don't have to worry about handlers forming a recursive chain and, worst case, running out of stack space, if the operations often complete immediately. With the skip enabled, the handler for the new operation would have to be called immediately if the operation returns right away.
The issue is that the handlers are supposed to execute both on success and on error. However, I don't know whether if an overlapped Read/Write/WSARecv/WSASend returning immediately with an error would still queue a completion packet, so that I can allow it to be handled in the handler by the thread pool, as in the case of success. Is this doable? Is it something that only applies to certain types of errors and not others? Workarounds?
This knowledge base article says that SUCCESS and ERROR_IO_PENDING result in a completion packet being generated and other results do not.
See Tip 4
Based on this blog from Raymond Chen, all completions will be queued to the completion port even if the operation completes synchronously (successfully or with an error condition).
If I call context.watch() on an ActorRef that is already dead, am I guaranteed to still receive a termination message?
Also, after having received a termination message regarding a specific actor, do I still need to call unwatch()?
Also, are watch() calls reference counted? If I call watch() twice, followed by unwatch() once, am I guaranteed to still get termination messages?
I think the documentation is pretty clear:
"One important property is that the message will be delivered
irrespective of the order in which the monitoring request and target’s
termination occur, i.e. you still get the message even if at the time
of registration the target is already dead."
http://doc.akka.io/docs/akka/2.0.1/general/supervision.html
And, you do not need to unwatch since the actor can't die twice, and it's not reference counted. It's binary.
Cheers,
√
I have a boost::thread which performs synchronous reads on a boost::asio::serial_port. When I destroy an instance of the class which contains both, I want the thread to end gracefully even if its blocked in a read call. How can I do this?
Looking at the docs, I tried cancel, but it works only for asynchronous reads/writes. Then I tried close, but I got an exception and it wasn't the kind you can recover from. Perhaps using send_break or native_handle? (this is Windows and portability's not critical)
Update: I also tried to stop the io_service I passed to the serial port object's constructor, but the read wasn't unblocked.
Edit: The exception is actually "catchable", but I'd hate to put a try/catch block inside a destructor, and refactoring the code to do the shutdown process outside the destructor would trigger lots of changes in upper layers. So I'd only go for this solution if some Boost authority says there is no other way.
There is no way to unblock the synchronous read as you ask to.
There are two options:
close/shutdown the port and catch an exception, which was raised
use asynchronous reads and cancel them, when you shutdown your application
The first one, of course, is not a good idea, because you cannot distinguish terminating application from error.
On close, you say that you get an exception that 'wasn't the kind you can recover from'.
What does this mean?
The solution seems to be to catch the exception. Why cannot you do that?
For the case when you want to distinguish between an error and program termination, set a flag on program termination before the close. In the exception handler ( catch ) check the flag. If set, handle as program termination, else handle as error.
You say that you do not wish to place a try/catch block inside a destructor. This seems like an odd prejudice to me, but OK there are other ways.
You can allow the exception to propagate all the way to the topmost catch block that surrounds all your code, and handle it there. ( You do have such a try/catch block protecting your entire application, of course :-)
Other ways are also possible ... but boss just dropped by
Add to the above question the concept of a wait/no wait indicator as a parameter to a ReadMessage function in a TCP/IP or UDP environment.
A third party function description states that:
This function is used to read a message from a queue which was defined by a previous registerforinput call. The input wait/no wait indicator will determine if this function will block on the queue specified, waiting for the data to be placed on the queue. If the nowait option is specified and no data is available a NULL pointer will be returned to the caller. When data available this function will return a pointer to the data read from the queue.
What does it mean for a function to be blocking or non-blocking?
Blocking means that execution of your code (in that thread) will stop for the duration of the call. Essentially, the function call will not return until the blocking operation is complete.
A blocking read will wait until there is data available (or a timeout, if any, expires), and then returns from the function call. A non-blocking read will (or at least should) always return immediately, but it might not return any data, if none is available at the moment.
An analogy if you'll permit me - sorry, it's late in the afternoon and I'm in the mood, if it gets down voted - ah well...
You want to get into a snazzy nightclub, but the bouncer tells you you cannot go in till someone comes out. You are effectively "blocked" on that condition. When someone comes out, you are free to go in - or some error condition such as "are those trainers?" Your night doesn't really kick off till you get in, your enjoyment is "blocked".
In a "non-blocking" scenario, you will tell the bouncer your phone number, and he will call you back when there is a free slot. So now you can do something else while waiting for someone to come out, you can start your night somewhere else and come back when called and continue there...
Sorry if that didn't help...
Take a look at this: http://www.scottklement.com/rpg/socktut/nonblocking.html
Here's some excerpts from it:
'By default, TCP sockets are in "blocking" mode. For example, when you call recv() to read from a stream, control isn't returned to your program until at least one byte of data is read from the remote site. This process of waiting for data to appear is referred to as "blocking".'
'Its possible to set a descriptor so that it is placed in "non-blocking" mode. When placed in non-blocking mode, you never wait for an operation to complete. This is an invaluable tool if you need to switch between many different connected sockets, and want to ensure that none of them cause the program to "lock up."'
Also, it's generally a good idea to try to search for an answer first (just type "blocking vs. non-blocking read" in a search engine), and then once you hit a wall there to come and ask questions that you couldn't find an answer to. The link I shared above was the second search result. Take a look at this great essay on what to do before asking questions on internet forums: http://www.catb.org/~esr/faqs/smart-questions.html#before
In your case, it means the function will not return until there actually is a message to return. It'll prevent your program from moving forward, but when it does move forward you'll have a message to work with.
If you specify nowait, a null pointer will be returned immediately if there are no messages on the queue, which allows you to process that situation.
I have two threads that use an event for synchronization.
In each thread they use the same call:
::CreateEvent( NULL,TRUE,FALSE,tcEventName )
The producer thread is the one that makes the call first, while the consumer thread makes the call last, so it's technically opening, not creating the event... I assume.
But, when SetEvent is called in the producer thread, the same event never gets triggered in the consumer thread (I'm using WaitForMultipleObjects())
Is there a tool that can tell me if the event is actually getting triggered properly.
Also, when I call CreateEvent() in each thread, the returned handle value is different for each... should they be the same?
Is there a better way to do this that will ensure it will work?
This is on Windows XP using Visual Studio 2005
Edit: I did some more checking and found that calling CreateEvent in the producer thread (the second one to call CreateEvent) sets LastError to 183 (ERROR_ALREADY_EXISTS),
however CreateEvent still returns a handle to the event...what gives? How can it error as already existing but still return a handle? Or is it supposed to do that?
According to the MSDN documentation for CreateEvent,
If the function succeeds, the return value is a handle to the event object. If the named event object existed before the function call, the function returns a handle to the existing object and GetLastError returns ERROR_ALREADY_EXISTS.
Based on your description, I don't see a problem with what you're doing. There's nothing I see to indicate you're doing something incorrectly. For me, though, I usually create the event once using CreateEvent() and then pass the handle to the thread(s) that I want to be signaled by that event. But there is nothing technically wrong with your approach.
You do realize that WaitForMultipleObjects() returns the index of the first signaled handle in the handles array, right? For example, if your named event is the second one in the list, but the first handle is signaled the vast majority of the time (e.g., by a fast-acting thread or a manual reset event that is signaled but never reset), WaitForMultipleObjects() will always return WAIT_OBJECT_0. In other words, your consumer thread will never see the fact that your named event is signaled because the first handle is "always" signaled. If this is the case, put your named event first in the list.
You don't happen to have the bWaitAll parameter to WaitForMultipleObjects() set to TRUE, do you? If you do, then all of the handles in the handles array have be signaled before the function returns.
Who calls ResetEvent() for your named event? It should be the consumer. It's not accidentally being called by some third-party thread, is it?
These are simply some things to double-check. If the event still doesn't behave as you expect, replace the WaitForMultipleObjects() with WaitForSingleObject() to see if your named event properly signals the consumer thread.
Hope this helps.
If you just use several threads in one process, why don't you pass event handle from one to another? As I know named kernel objects created to share them between processes.
Also you can try to use OpenEvent function to open already created event. This might give some ideas.
Your code should work as you've described it. If the event already exists when you try to create it, you will get a handle to the existing event.
Handles are different per-thread, so you needn't worry if they are different (they should be).
I suggest you simplify a little bit to see if things are working the way you expect. The fact that you're using WaitForMultipleObjects() tells me you have other stuff going on. If you think it's not working, get rid of the other stuff and see if you can figure it out.
In a single process you only have to call CreateEvent once and share the handle returned in all threads.
Also, you do not need to name the Event unless you want external processes to access the event with OpenEvent. In fact, if you name the event, only one copy of your program will be able to call CreateEvent successfully.