message order incorrect (using io_service::wrap) - c++

I've an application to which a GUI connects and receives a lot of messages and the problem is that every once in a while it receives a message out of order.
The connection runs on a separate worker thread (a separate io_service) and exposes the send function(which does a async__write) via io_service::wrap as a callback for others to invoke with a string message as parameter. (i.e. callback = io_service_.wrap(boost::bind(&SomeGUIClass::send,this,_1));),
so to send something to the GUI client, the others call callback(stringMessage) - which should correctly dispatch the send function call on the io_service's queue.
messages are in correct order before invoking the callback, but I can see that sometimes they are out of order within the callback,just before the write call.
my reasoning: wrap translates to a dispatch which will try to call the wrapped fn. within the callback (if it can meet the thread safety guarantees) , and schedule it for later if it cannot.
thus sometimes earlier messages get scheduled for a later write and the latest messages get processed since dispatch was able to process it within the same callback.
please let me know if this reasoning is correct, any ideas appreciated.
thanks!

it was a bug, and thus the attendant confusion. (was making the mistake of calling io_service::run from 2 separate threads wihout realising.) now realized, and problem solved. thanks!

Related

Asio async handler is never called, no other handler invoked

I have a asio sync connection. ioService is in one thread (I have only one thread.).
Smaller problem:
boost::asio::async_write(m_socket, boost::asio::buffer(requestStr.data(), requestStr.size()), handler);
The handler is never called, but the server gets it and replies that I get.
The bigger problem:
boost::asio::async_read_until(m_socket, sbuf, '\n', sendingHandler);
It also doesn't call the handler. The sbuf is immediately filled and I can read it there, but I don't know the position of the deliminator. Therefore I need the handler to get the bytes_transferred parameter. (I'm not going to iterate the buffer.)
I tried several things and I could invoke the handler once, but I don't remember what the issue was about after a small refract. Any help? Thanks!
When I used sync messaging, everything was fine, but there is no timeout there.
EDIT:
If you know any nice solution to find the deliminator I don't need the handler.
Because, I would send the msg sync_write and read async.
It wont be called, because it is async. Async methods for writing and reading never call handlers from within the place they're called:
Regardless of whether the asynchronous operation completes immediately
or not, the handler will not be invoked from within this function.
Invocation of the handler will be performed in a manner equivalent to
using boost::asio::io_service::post().
You need to manually call io_service methods like run or run_once to perform operations and that is the moment when your callback will be called.

What is the difference between post and dispatch in boost::asio?

I am trying to use boost:asio library to create a threadpool. The official documentation says :
dispatch : Request the io_service to invoke the given handler.
post: Request the io_service to invoke the given handler and return immediately.
Could someone explain how these two differ ?
The difference is dispatch may run handler (the CompletionHandler passed to it) inside it which means you will wait for it to finish, if it does, before the function returns. post on the other hand will not run handler itself and returns back to the call site immediately.
So, dispatch is a potentially blocking call while post is a non-blocking call.
Post ensures that the thread that calls post will not immediately attempt to process the task.
https://www.boost.org/doc/libs/1_47_0/doc/html/boost_asio/reference/io_service/post.html
but without allowing the io_service to call the handler from inside
this function.
Dispatch makes no such promise; and may be completed by the time the function returns.

Asynchronous Completion Handling

I have this situation:
void foo::bar()
{
RequestsManager->SendRequest(someRequest, this, &foo::someCallback);
}
where RequestsManager works in asynchronous way:
SendRequest puts the request in a queue and returns to the caller
Other thread gets the requests from the queue and process them
When one request is processed the callback is called
Is it possible to have foo::someCallback called in the same thread as SendRequest? If not, how may I avoid following "callback limitation": callbacks should not make time consuming operations to avoid blocking the requests manager.
No - calls/callbacks cannot change thread context - you have to issue some signal to communicate between threads.
Typically, 'someCallback' would either signal an event upon which the thread that originated the 'SendRequest' call is waiting on, (synchronous call), or push the SendRequest, (and so, presumably, results from its processing), onto a queue upon which the thread that originated the 'SendRequest' call will eventually pop , (asynchronous). Just depends on how the originator wshes to be signaled..
Aynch example - the callback might PostMessage/Dispatcher.BeginInvoke the completed SendRequest to a GUI thread for display of the results.
I can see few ways how to achieve it:
A) Implement strategy similar to signal handling
When request processing is over RequestManager puts callback invocation on the waiting list. Next time SendRequest is called, right before returning execution it will check are there any pending callbacks for the thread and execute them. This is relatively simple approach with minimal requirements on the client. Choose it if latency is not of a concern. RequestManager can expose API to forcefully check for pending callbacks
B) Suspend callback-target thread and execute callback in the third thread
This will give you true asynchronous solution with all its caveats. It will look like target-thread execution got interrupted and execution jumped into interrupt handler. Before callback returns target thread needs to be resumed. You wont be able to access thread local storage or original thread's stack from inside the callback.
Depends on "time-consuming operations"'s definition.
The classic way to do this is:
when the request is processed, the RequestManager should execute that &foo::someCallback
to avoid blocking the request manager, you may just rise a flag inside this callback
check that flag periodically inside the thread, which called RequestsManager->SendRequest
This flag will be just a volatile bool inside class foo
If you want to make sure, that the calling thread (foo's) will understand immediately, that the request has been processed, you need additional synchronization.
Implement (or use already implemented) blocking pipe (or use signals/events) between these threads. The idea is:
foo's thread executes SendRequest
foo starts sleeping on some select (for example)
RequestManager executes the request and:
calls &foo::someCallback
"awakes" the foo's thread (by sending something in that file descriptor, which foo sleeps on (using select))
foo is awaken
checks the volatile bool flag for already processed request
does what it needs to do
annuls the flag

thread-safe function pointers in C++

I'm writing a network library that a user can pass a function pointer to for execution on certain network events. In order to keep the listening loop from holding up the developer's application, I pass the event handler to a thread. Unfortunately, this creates a bit of a headache for handling things in a thread-safe manner. For instance, if the developer passes a function that makes calls to their Windows::Forms application's elements, then an InvalidOperationException will be thrown.
Are there any good strategies for handling thread safety?
Function pointers can not be thread safe as they declare a point to call. So they are just pointers.
Your code always runs in the thread it was called from (via the function pointer).
What you want to achieve is that your code runs in a specific thread (maybe the UI thread).
For this you must use some kind of queue to synchronize the invocation into the MainThread.
This is exactly what .Net's BeginInvoke()/Invoke() on a Form do. The queue is in that case (somewhere deep inside the .NET framework) the windows message queue.
But you can use any other queue as long as the "correct" thread reads and executes the call requests from that queue.

Creating/Opening Events in C++ and checking if they are fired

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.