Deadlock when dispatching notification in notification handler using Poco::NotificationCenter - c++

I'm using Poco as part of a C++ app and I've run into an issue I don't quite understand. The app was translated from Obj-C and made heavy use of Apple's NSNotificationCenter.
To make the transition as painless as possible, I decided to use Poco's NotificationCenter instead. It works fine but I had some users reporting deadlocks I'm now trying to resolve.
Just a quick heads-up for those not familiar with NotificationCenter. You signup for a notification like this:
Poco::NotificationCenter& nc = Poco::NotificationCenter::defaultCenter();
nc.addObserver(Poco::NObserver<MyClass, MyNotification>(*this, &MyClass::onNotification));
and post a notification like this:
Poco::NotificationCenter& nc = Poco::NotificationCenter::defaultCenter();
nc.postNotification(new MyNotification());
The postNotification() method is defined like this:
void NotificationCenter::postNotification(Notification::Ptr pNotification)
{
poco_check_ptr (pNotification);
ScopedLockWithUnlock<Mutex> lock(_mutex);
ObserverList observersToNotify(_observers);
lock.unlock();
for (ObserverList::iterator it = observersToNotify.begin(); it != observersToNotify.end(); ++it)
{
(*it)->notify(pNotification);
}
}
And NObserver::notify() like this:
void notify(Notification* pNf) const
{
Poco::Mutex::ScopedLock lock(_mutex);
if (_pObject)
{
N* pCastNf = dynamic_cast<N*>(pNf);
if (pCastNf)
{
NotificationPtr ptr(pCastNf, true);
(_pObject->*_method)(ptr);
}
}
}
This is all really simple and doesn't involve any black magic.
Given the fact that the postNotification method always iterates over all observers (AFTER locking one and before checking if the type of the notification matches using a dynamic typecast) I'm assuming that this MUST always cause a deadlock when a notification is sent from a notification handler as it would also try to access the observer where itself is called from and will wait forever on the lock in NObserver::notify()?
From the process samples my users sent me it looks like my assumption is correct.
But for some reason this doesn't appear to deadlock in most cases (I never experienced it ever myself). I just stepped through with the debugger and couldn't make it lock up. Does anyone have an explanation why this only locks up under certain circumstances?

Related

Implementing a custom async task type and await

I am developing a C++ app in which i need to receive messages from an MQ and then parsing them according to their type and for a particular reason I want to make this process (receiving a single message followed by processing it) asynchronous. Since, I want to keep things as simple as possible in a way that the next developer would have no problem continuing the code, I have written a very small class to implement Asynchrony.
I first raise a new thread and pass a function to the thread:
task = new thread([&] {
result = fn();
isCompleted = true;
});
task->detach();
and in order to await the task I do the following:
while (!isCompleted && !(*cancelationToken))
{
Sleep(5);
}
state = 1; // marking the task as completed
So far there is no problem and I have not faced any bug or error but I am not sure if this is "a good way to do this" and my question is focused on determining this.
Read about std::future and std::async.
If your task runs in another core or processor, the variable isCompleted may become un-synchronized having two copies in core cache. So you may be waiting more than needed.
If you have to wait for something it is better to use a semaphore.
As said in comments, using standard methods is better anyway.

Boost HTTP server issue

I'm starting to use Boost, so may be I'm messing something up.
I'm trying to set up http server with boost (ASIO). I've taken the code from docs: http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/examples/cpp03_examples.html (HTTP Server, the first one)
The only difference from the example is I'm running server by my own method "run" and starting io_service in background thread, like in the docs: http://www.boost.org/doc/libs/1_54_0/doc/html/boost_asio/reference/io_service.html
boost::asio::io_service::work work(io_service_);
(Also I'm stopping io_service from my run method too.)
When I'm starting this modified server everything seems to be OK, run method is working fine. But then I'm trying to get a doc from the server the request hangs and control flow never comes to "request_handle" method.
Am I missing something?
UPD. Here is my code of run method:
void NetstreamServer::run()
{
LOG4CPLUS_DEBUG(logger, "NetstreamServer is running");
boost::asio::io_service::work work(io_service_);
try
{
while (true)
{
if (condition)
{
io_service_.stop();
break;
}
}
}
catch (std::exception const& e)
{
LOG4CPLUS_ERROR(logger, "NetstreamServer" << " caught exception: " << e.what());
}
}
You should call io_service_::run() - otherwise no one will dispatch the completion handlers of Asio objects serviced by io_service_.
Without including the code you changed, everyone here can only guess. Unfortunately you also do not include the compiler and the OS you are using. Even with boost claiming it is platform independent, you should always include this information, as it reality, platforms are different even with boost.
Let me do a guess. You use Microsoft Windows? How do you prevent the "main" function to exit? You moved the blocking "run" function out of it in another thread, the main function has no wait point anymore. Let me guess again, you used something like "getchar". With that, you can exit your server with only hitting the keyboard return key. If yes, the problem is the getchar, with unfortunately blocks every io of the asio socket implementation, but only on Windows based systems.
I would not need to guess if you would include the informations mentioned in your post. In particular all(!) changes you made to the code sample.

Boost Asio callback doesn't get called

I'm using Boost.Asio for network operations, they have to (and actually, can, there's no complex data structures or anything) remain pretty low level since I can't afford the luxury of serialization overhead (and the libs I found that did offer well enough performance seemed to be badly suited for my case).
The problem is with an async write I'm doing from the client (in QT, but that should probably be irrelevant here). The callback specified in the async_write doesn't get called, ever, and I'm at a complete loss as to why. The code is:
void SpikingMatrixClient::addMatrix() {
std::cout << "entered add matrix" << std::endl;
int action = protocol::Actions::AddMatrix;
int matrixSize = this->ui->editNetworkSize->text().toInt();
std::ostream out(&buf);
out.write(reinterpret_cast<const char*>(&action), sizeof(action));
out.write(reinterpret_cast<const char*>(&matrixSize), sizeof(matrixSize));
boost::asio::async_write(*connection.socket(), buf.data(),
boost::bind(&SpikingMatrixClient::onAddMatrix, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
}
which calls the first write. The callback is
void SpikingMatrixClient::onAddMatrix(const boost::system::error_code& error, size_t bytes_transferred) {
std::cout << "entered onAddMatrix" << std::endl;
if (!error) {
buf.consume(bytes_transferred);
requestMatrixList();
} else {
QString message = QString::fromStdString(error.message());
this->ui->statusBar->showMessage(message, 15000);
}
}
The callback never gets called, even though the server receives all the data. Can anyone think of any reason why it might be doing that?
P.S. There was a wrapper for that connection, and yes there will probably be one again. Ditched it a day or two ago because I couldn't find the problem with this callback.
As suggested, posting a solution I found to be the most suitable (at least for now).
The client application is [being] written in QT, and I need the IO to be async. For the most part, the client receives calculation data from the server application and has to render various graphical representations of them.
Now, there's some key aspects to consider:
The GUI has to be responsive, it should not be blocked by the IO.
The client can be connected / disconnected.
The traffic is pretty intense, data gets sent / refreshed to the client every few secs and it has to remain responsive (as per item 1.).
As per the Boost.Asio documentation,
Multiple threads may call io_service::run() to set up a pool of
threads from which completion handlers may be invoked.
Note that all threads that have joined an io_service's pool are considered equivalent, and the io_service may distribute work across them in an arbitrary fashion.
Note that io_service.run() blocks until the io_service runs out of work.
With this in mind, the clear solution is to run io_service.run() from another thread. The relevant code snippets are
void SpikingMatrixClient::connect() {
Ui::ConnectDialog ui;
QDialog *dialog = new QDialog;
ui.setupUi(dialog);
if (dialog->exec()) {
QString host = ui.lineEditHost->text();
QString port = ui.lineEditPort->text();
connection = TcpConnection::create(io);
boost::system::error_code error = connection->connect(host, port);
if (!error) {
io = boost::shared_ptr<boost::asio::io_service>(new boost::asio::io_service);
work = boost::shared_ptr<boost::asio::io_service::work>(new boost::asio::io_service::work(*io));
io_threads.create_thread(boost::bind(&SpikingMatrixClient::runIo, this, io));
}
QString message = QString::fromStdString(error.message());
this->ui->statusBar->showMessage(message, 15000);
}
}
for connecting & starting IO, where:
work is a private boost::shared_ptr to the boost::asio::io_service::work object it was passed,
io is a private boost::shared_ptr to a boost::asio::io_service,
connection is a boost::shared_ptr to my connection wrapper class, and the connect() call uses a resolver etc. to connect the socket, there's plenty examples of that around
and io_threads is a private boost::thread_group.
Surely it could be shortened with some typedefs if needed.
TcpConnection is my own connection wrapper implementation, which sortof lacks functionality for now, and I suppose I could move the whole thread thing into it when it gets reinstated. This snippet should be enough to get the idea anyway...
The disconnecting part goes like this:
void SpikingMatrixClient::disconnect() {
work.reset();
io_threads.join_all();
boost::system::error_code error = connection->disconnect();
if (!error) {
connection.reset();
}
QString message = QString::fromStdString(error.message());
this->ui->statusBar->showMessage(message, 15000);
}
the work object is destroyed, so that the io_service can run out of work eventually,
the threads are joined, meaning that all work gets finished before disconnecting, thus data shouldn't get corrupted,
the disconnect() calls shutdown() and close() on the socket behind the scenes, and if there's no error, destroys the connection pointer.
Note, that there's no error handling in case of an error while disconnecting in this snippet, but it could very well be done, either by checking the error code (which seems more C-like), or throwing from the disconnect() if the error code within it represents an error after trying to disconnect.
I encountered a similar problem (callbacks not fired) but the circumstances are different from this question (io_service had jobs but still would not fire the handlers ). I will post this anyway and maybe it will help someone.
In my program, I set up an async_connect() then followed by io_service.run(), which blocks as expected.
async_connect() goes to on_connect_handler() as expected, which in turn fires async_write().
on_write_complete_handler() does not fire, even though the other end of the connection has received all the data and has even sent back a response.
I discovered that it is caused by me placing program logic in on_connect_handler(). Specifically, after the connection was established and after I called async_write(), I entered an infinite loop to perform arbitrary logic, not allowing on_connect_handler() to exit. I assume this causes the io_service to not be able to execute other handlers, even if their conditions are met because it is stuck here. ( I had many misconceptions, and thought that io_service would automagically spawn threads for each async_x() call )
Hope that helps.

Symbian C++ - synchronous Bluetooth discovery with timeout using RHostResolver

I am writing an application in Qt to be deployed on Symbian S60 platform. Unfortunately, it needs to have Bluetooth functionality - nothing really advanced, just simple RFCOMM client socket and device discovery. To be exact, the application is expected to work on two platforms - Windows PC and aforementioned S60.
Of course, since Qt lacks Bluetooth support, it has to be coded in native API - Winsock2 on Windows and Symbian C++ on S60 - I'm coding a simple abstraction layer. And I have some problems with the discovery part on Symbian.
The discovery call in the abstraction layer should work synchronously - it blocks until the end of the discovery and returns all the devices as a QList. I don't have the exact code right now, but I had something like that:
RHostResolver resolver;
TInquirySockAddr addr;
// OMITTED: resolver and addr initialization
TRequestStatus err;
TNameEntry entry;
resolver.GetByAddress(addr, entry, err);
while (true) {
User::WaitForRequest(err);
if (err == KErrHostResNoMoreResults) {
break;
} else if (err != KErrNone) {
// OMITTED: error handling routine, not very important right now
}
// OMITTED: entry processing, adding to result QList
resolver.Next(entry, err);
}
resolver.Close();
Yes, I know that User::WaitForRequest is evil, that coding Symbian-like, I should use active objects, and so on. But it's just not what I need. I need a simple, synchronous way of doing device discovery.
And the code above does work. There's one quirk, however - I'd like to have a timeout during the discovery. That is, I want the discovery to take no more than, say, 15 seconds - parametrized in a function call. I tried to do something like this:
RTimer timer;
TRequestStatus timerStatus;
timer.CreateLocal();
RHostResolver resolver;
TInquirySockAddr addr;
// OMITTED: resolver and addr initialization
TRequestStatus err;
TNameEntry entry;
timer.After(timerStatus, timeout*1000000);
resolver.GetByAddress(addr, entry, err);
while (true) {
User::WaitForRequest(err, timerStatus);
if (timerStatus != KRequestPending) { // timeout
resolver.Cancel();
User::WaitForRequest(err);
break;
}
if (err == KErrHostResNoMoreResults) {
timer.Cancel();
User::WaitForRequest(timerStatus);
break;
} else if (err != KErrNone) {
// OMITTED: error handling routine, not very important right now
}
// OMITTED: entry processing, adding to result QList
resolver.Next(entry, err);
}
timer.Close();
resolver.Close();
And this code kinda works. Even more, the way it works is functionally correct - the timeout works, the devices discovered so far are returned, and if the discovery ends earlier, then it exits without waiting for the timer. The problem is - it leaves a stray thread in the program. That means, when I exit my app, its process is still loaded in background, doing nothing. And I'm not the type of programmer who would be satisfied with a "fix" like making the "exit" button kill the process instead of exiting gracefully. Leaving a stray thread seems a too serious resource leak.
Is there any way to solve this? I don't mind rewriting everything from scratch, even using totally different APIs (as long as we're talking about native Symbian APIs), I just want it to work. I've read a bit about active objects, but it doesn't seem like what I need, since I just need this to work synchronously... In the case of bigger changes, I would appreciate more detailed explanations, since I'm new to Symbian C++, and I don't really need to master it - this little Bluetooth module is probably everything I'll need to write in it in foreseeable future.
Thanks in advance for any help! :)
The code you have looks ok to me. You've missed the usual pitfall of not consuming all the requests that you've issued. Assuming that you also cancel the timer and do a User::WaitForRequest(timerStatus) inside you're error handing condition, it should work.
I'm guessing that what you're worrying about is that there's no way for your main thread to request that this thread exit. You can do this roughly as follows:
Pass a pointer to a TRequestStatus into the thread when it is created by your main thread. Call this exitStatus.
When you do the User::WaitForRequest, also wait on exitStatus.
The main thread will do a bluetoothThread.RequestComplete(exitStatus, KErrCancel) when it wants the subthread to exit, where bluetoothThread is the RThread object that the main thread created.
in the subthread, when exitStatus is signalled, exit the loop to terminate the thread. You need to make sure you cancel and consume the timer and bluetooth requests.
the main thread should do a bluetoothThread.Logon and wait for the signal to wait for the bluetooth thread to exit.
There will likely be some more subtleties to deal correctly with all the error cases and so on.
I hope I'm not barking up the wrong tree altogether here...
The question is already answered, but... If you'd use active objects, I'd propose you to use nested active scheduler (class CActiveSchedulerWait). You could then pass it to your active objects (CPeriodic for timer and some other CActive for Bluetooth), and one of them would stop this nested scheduler in its RunL() method. More than this, with this approach your call becomes synchronous for the caller, and your thread will be gracefully closed after performing the call.
If you're interested in the solution, search for examples of CActiveSchedulerWait, or just ask me and I'll give your some code sample.

Handling Interrupt in C++

I am writing a framework for an embedded device which has the ability to run multiple applications. When switching between apps how can I ensure that the state of my current application is cleaned up correctly? For example, say I am running through an intensive loop in one application and a request is made to run a second app while that loop has not yet finished. I cannot delete the object containing the loop until the loop has finished, yet I am unsure how to ensure the looping object is in a state ready to be deleted. Do I need some kind of polling mechanism or event callback which notifies me when it has completed?
Thanks.
Usually if you need to do this type of thing you'll have an OS/RTOS that can handle the multiple tasks (even if the OS is a simple homebrew type thing).
If you don't already have an RTOS, you may want to look into one (there are hundreds available) or look into incorporating something simple like protothreads: http://www.sics.se/~adam/pt/
So you have two threads: one running the kernel and one running the app? You will need to make a function in your kernel say ReadyToYield() that the application can call when it's happy for you to close it down. ReadyToYield() would flag the kernel thread to give it the good news and then sit and wait until the kernel thread decides what to do. It might look something like this:
volatile bool appWaitingOnKernel = false;
volatile bool continueWaitingForKernel;
On the app thread call:
void ReadyToYield(void)
{
continueWaitingForKernel = true;
appWaitingOnKernel = true;
while(continueWaitingForKernel == true);
}
On the kernel thread call:
void CheckForWaitingApp(void)
{
if(appWaitingOnKernel == true)
{
appWaitingOnKernel = false;
if(needToDeleteApp)
DeleteApp();
else
continueWaitingForKernel = false;
}
}
Obviously, the actual implementation here depends on the underlying O/S but this is the gist.
John.
(1) You need to write thread-safe code. This is not specific to embedded systems.
(2) You need to save state away when you do a context switch.