Reputation: 20790
I have this situation:
void foo::bar()
{
RequestsManager->SendRequest(someRequest, this, &foo::someCallback);
}
where RequestsManager works in asynchronous way:
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.
Upvotes: 0
Views: 197
Reputation: 2594
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.
Upvotes: 1
Reputation: 38173
Depends on "time-consuming operations"'s definition.
The classic way to do this is:
RequestManager
should execute that &foo::someCallback
RequestsManager->SendRequest
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:
&foo::someCallback
foo
's thread (by sending something in that file descriptor, which foo
sleeps on (using select
))foo
is awakenvolatile bool
flag for already processed requestUpvotes: 1
Reputation: 24867
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.
Upvotes: 3