chat-dialog-backend: handle exit properly
Change-Id: Iadab00119f6247e90cfc9ee585b9506f88876e47
diff --git a/src/chat-dialog-backend.cpp b/src/chat-dialog-backend.cpp
index 680d24b..bedb45d 100644
--- a/src/chat-dialog-backend.cpp
+++ b/src/chat-dialog-backend.cpp
@@ -36,7 +36,6 @@
, m_userChatPrefix(userChatPrefix)
, m_chatroomName(chatroomName)
, m_nick(nick)
- , m_scheduler(m_face.getIoService())
{
updatePrefixes();
}
@@ -50,9 +49,21 @@
void
ChatDialogBackend::run()
{
- initializeSync();
+ bool shouldResume = false;
+ do {
+ initializeSync();
- m_face.processEvents();
+ if (m_face == nullptr)
+ break;
+
+ m_face->getIoService().run();
+
+ m_mutex.lock();
+ shouldResume = m_shouldResume;
+ m_shouldResume = false;
+ m_mutex.unlock();
+
+ } while (shouldResume);
std::cerr << "Bye!" << std::endl;
}
@@ -61,33 +72,43 @@
void
ChatDialogBackend::initializeSync()
{
- // if a SyncSocket is running, turn it off
- if (static_cast<bool>(m_sock)) {
- if (m_joined)
- sendLeave();
- m_sock.reset();
+ BOOST_ASSERT(m_sock == nullptr);
- usleep(100000);
- }
+ m_face = unique_ptr<ndn::Face>(new ndn::Face);
+ m_scheduler = unique_ptr<ndn::Scheduler>(new ndn::Scheduler(m_face->getIoService()));
// create a new SyncSocket
m_sock = make_shared<chronosync::Socket>(m_chatroomPrefix,
m_routableUserChatPrefix,
- ref(m_face),
+ ref(*m_face),
bind(&ChatDialogBackend::processSyncUpdate, this, _1));
// schedule a new join event
- m_scheduler.scheduleEvent(time::milliseconds(600),
- bind(&ChatDialogBackend::sendJoin, this));
+ m_scheduler->scheduleEvent(time::milliseconds(600),
+ bind(&ChatDialogBackend::sendJoin, this));
// cancel existing hello event if it exists
- if (static_cast<bool>(m_helloEventId)) {
- m_scheduler.cancelEvent(m_helloEventId);
+ if (m_helloEventId != nullptr) {
+ m_scheduler->cancelEvent(m_helloEventId);
m_helloEventId.reset();
}
}
void
+ChatDialogBackend::close()
+{
+ if (m_joined)
+ sendLeave();
+
+ usleep(100000);
+
+ m_scheduler->cancelAllEvents();
+ m_helloEventId.reset();
+ m_roster.clear();
+ m_sock.reset();
+}
+
+void
ChatDialogBackend::processSyncUpdate(const std::vector<chronosync::MissingDataInfo>& updates)
{
_LOG_DEBUG("<<< processing Tree Update");
@@ -156,7 +177,7 @@
if (it != m_roster.end()) {
// cancel timeout event
if (static_cast<bool>(it->second.timeoutEventId))
- m_scheduler.cancelEvent(it->second.timeoutEventId);
+ m_scheduler->cancelEvent(it->second.timeoutEventId);
// notify frontend to remove the remote session (node)
emit sessionRemoved(QString::fromStdString(remoteSessionPrefix.toUri()),
@@ -193,13 +214,13 @@
// If a timeout event has been scheduled, cancel it.
if (static_cast<bool>(it->second.timeoutEventId))
- m_scheduler.cancelEvent(it->second.timeoutEventId);
+ m_scheduler->cancelEvent(it->second.timeoutEventId);
// (Re)schedule another timeout event after 3 HELLO_INTERVAL;
it->second.timeoutEventId =
- m_scheduler.scheduleEvent(HELLO_INTERVAL * 3,
- bind(&ChatDialogBackend::remoteSessionTimeout,
- this, remoteSessionPrefix));
+ m_scheduler->scheduleEvent(HELLO_INTERVAL * 3,
+ bind(&ChatDialogBackend::remoteSessionTimeout,
+ this, remoteSessionPrefix));
// If chat message, notify the frontend
if (msg.type() == SyncDemo::ChatMessage::CHAT)
@@ -262,8 +283,8 @@
prepareControlMessage(msg, SyncDemo::ChatMessage::JOIN);
sendMsg(msg);
- m_helloEventId = m_scheduler.scheduleEvent(HELLO_INTERVAL,
- bind(&ChatDialogBackend::sendHello, this));
+ m_helloEventId = m_scheduler->scheduleEvent(HELLO_INTERVAL,
+ bind(&ChatDialogBackend::sendHello, this));
emit sessionAdded(QString::fromStdString(m_routableUserChatPrefix.toUri()),
QString::fromStdString(msg.from()),
@@ -277,8 +298,8 @@
prepareControlMessage(msg, SyncDemo::ChatMessage::HELLO);
sendMsg(msg);
- m_helloEventId = m_scheduler.scheduleEvent(HELLO_INTERVAL,
- bind(&ChatDialogBackend::sendHello, this));
+ m_helloEventId = m_scheduler->scheduleEvent(HELLO_INTERVAL,
+ bind(&ChatDialogBackend::sendHello, this));
}
void
@@ -366,22 +387,26 @@
updatePrefixes();
- initializeSync();
+ m_mutex.lock();
+ m_shouldResume = true;
+ m_mutex.unlock();
+
+ close();
+
+ m_face->getIoService().stop();
}
}
void
ChatDialogBackend::shutdown()
{
- if (static_cast<bool>(m_sock)) {
- if (m_joined)
- sendLeave();
- m_sock.reset();
+ m_mutex.lock();
+ m_shouldResume = false;
+ m_mutex.unlock();
- usleep(100000);
- }
+ close();
- m_face.getIoService().stop();
+ m_face->getIoService().stop();
}
} // namespace chronos
diff --git a/src/chat-dialog-backend.hpp b/src/chat-dialog-backend.hpp
index 09c52a6..f2d6f89 100644
--- a/src/chat-dialog-backend.hpp
+++ b/src/chat-dialog-backend.hpp
@@ -59,6 +59,9 @@
initializeSync();
void
+ close();
+
+ void
processSyncUpdate(const std::vector<chronosync::MissingDataInfo>& updates);
void
@@ -129,7 +132,7 @@
private:
typedef std::map<ndn::Name, UserInfo> BackendRoster;
- ndn::Face m_face;
+ unique_ptr<ndn::Face> m_face;
Name m_localRoutingPrefix; // routable local prefix
Name m_chatroomPrefix; // chatroom sync prefix
@@ -141,12 +144,15 @@
shared_ptr<chronosync::Socket> m_sock; // SyncSocket
- ndn::Scheduler m_scheduler; // scheduler
+ unique_ptr<ndn::Scheduler> m_scheduler;// scheduler
ndn::EventId m_helloEventId; // event id of timeout
bool m_joined; // true if in a chatroom
BackendRoster m_roster; // User roster
+
+ QMutex m_mutex;
+ bool m_shouldResume;
};
} // namespace chronos
diff --git a/src/common.hpp b/src/common.hpp
index 9b427b6..9acb3b7 100644
--- a/src/common.hpp
+++ b/src/common.hpp
@@ -45,17 +45,18 @@
using boost::noncopyable;
-using ndn::shared_ptr;
-using ndn::weak_ptr;
-using ndn::enable_shared_from_this;
-using ndn::make_shared;
-using ndn::static_pointer_cast;
-using ndn::dynamic_pointer_cast;
-using ndn::const_pointer_cast;
-using ndn::function;
-using ndn::bind;
-using ndn::ref;
-using ndn::cref;
+using std::shared_ptr;
+using std::unique_ptr;
+using std::weak_ptr;
+using std::enable_shared_from_this;
+using std::make_shared;
+using std::static_pointer_cast;
+using std::dynamic_pointer_cast;
+using std::const_pointer_cast;
+using std::function;
+using std::bind;
+using std::ref;
+using std::cref;
using ndn::Interest;
using ndn::Data;