summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRemko Tronçon <git@el-tramo.be>2014-01-17 20:02:19 (GMT)
committerRemko Tronçon <git@el-tramo.be>2014-01-18 10:44:42 (GMT)
commit85c46a0fcce3495fe94397d53791628a8ccc74c4 (patch)
tree233decfdbe1c221f3db2149f0f59d828173c102e
parent09108f5ac3c1a6567730b5bbd0c847f8422ff4a2 (diff)
downloadswift-85c46a0fcce3495fe94397d53791628a8ccc74c4.zip
swift-85c46a0fcce3495fe94397d53791628a8ccc74c4.tar.bz2
Sluift: Allow blocking calls to be interrupted.
Change-Id: I3755e796fbddc038022bbf543c7b1c0529a9b0f9
-rw-r--r--Sluift/Examples/Login.lua4
-rw-r--r--Sluift/SConscript1
-rw-r--r--Sluift/SluiftGlobals.h6
-rw-r--r--Sluift/Watchdog.cpp50
-rw-r--r--Sluift/Watchdog.h28
-rw-r--r--Sluift/client.cpp1
-rw-r--r--Sluift/main.cpp10
7 files changed, 74 insertions, 26 deletions
diff --git a/Sluift/Examples/Login.lua b/Sluift/Examples/Login.lua
index c43b72a..fadb651 100644
--- a/Sluift/Examples/Login.lua
+++ b/Sluift/Examples/Login.lua
@@ -1,5 +1,5 @@
--[[
- Copyright (c) 2010-2013 Remko Tronçon
+ Copyright (c) 2010-2014 Remko Tronçon
Licensed under the GNU General Public License v3.
See Documentation/Licenses/GPLv3.txt for more information.
--]]
@@ -21,7 +21,7 @@ sluift.debug = os.getenv("SLUIFT_DEBUG") or false
print("Connecting " .. os.getenv("SLUIFT_JID") .. " ...")
c = sluift.new_client(os.getenv("SLUIFT_JID"), os.getenv("SLUIFT_PASS"))
-c:set_options({compress = false, tls = false})
+c:set_options{compress = false, tls = false}
c:connect()
c:send_presence("")
diff --git a/Sluift/SConscript b/Sluift/SConscript
index d88e948..38baef1 100644
--- a/Sluift/SConscript
+++ b/Sluift/SConscript
@@ -32,6 +32,7 @@ elif env["SCONS_STAGE"] == "build" :
"ElementConvertors/CommandConvertor.cpp",
"ClientHelpers.cpp",
"SluiftClient.cpp",
+ "Watchdog.cpp",
"core.c",
"client.cpp",
"sluift.cpp"
diff --git a/Sluift/SluiftGlobals.h b/Sluift/SluiftGlobals.h
index 18a90c2..0d8e637 100644
--- a/Sluift/SluiftGlobals.h
+++ b/Sluift/SluiftGlobals.h
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013 Remko Tronçon
+ * Copyright (c) 2013-2014 Remko Tronçon
* Licensed under the GNU General Public License.
* See the COPYING file for more information.
*/
@@ -9,10 +9,11 @@
#include <Sluift/LuaElementConvertors.h>
#include <Swiften/EventLoop/SimpleEventLoop.h>
#include <Swiften/Network/BoostNetworkFactories.h>
+#include <signal.h>
namespace Swift {
struct SluiftGlobals {
- SluiftGlobals() : networkFactories(&eventLoop) {}
+ SluiftGlobals() : networkFactories(&eventLoop), interruptRequested(0) {}
int timeout;
bool debug;
@@ -20,5 +21,6 @@ namespace Swift {
SimpleEventLoop eventLoop;
BoostNetworkFactories networkFactories;
int coreLibIndex;
+ sig_atomic_t interruptRequested;
};
}
diff --git a/Sluift/Watchdog.cpp b/Sluift/Watchdog.cpp
new file mode 100644
index 0000000..8b1c9ab
--- /dev/null
+++ b/Sluift/Watchdog.cpp
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2014 Remko Tronçon
+ * Licensed under the GNU General Public License.
+ * See the COPYING file for more information.
+ */
+
+#include <Sluift/Watchdog.h>
+
+#include <Sluift/globals.h>
+
+static const int INTERVAL_MS = 500;
+
+
+using namespace Swift;
+
+Watchdog::Watchdog(int timeout, TimerFactory* timerFactory) :
+ remainingTime(timeout),
+ timerFactory(timerFactory),
+ timedOut(false) {
+ Sluift::globals.interruptRequested = 0;
+
+ int nextTimeout = remainingTime >= 0 ? std::min(remainingTime, INTERVAL_MS) : INTERVAL_MS;
+
+ timer = timerFactory->createTimer(nextTimeout);
+ timer->onTick.connect(boost::bind(&Watchdog::handleTimerTick, this));
+ remainingTime -= nextTimeout;
+ timer->start();
+}
+
+Watchdog::~Watchdog() {
+ if (timer) {
+ timer->stop();
+ }
+}
+
+void Watchdog::handleTimerTick() {
+ if (Sluift::globals.interruptRequested || remainingTime == 0) {
+ timedOut = true;
+ }
+ else {
+ int nextTimeout = remainingTime >= 0 ? std::min(remainingTime, INTERVAL_MS) : INTERVAL_MS;
+ if (nextTimeout != INTERVAL_MS) {
+ timer->onTick.disconnect(boost::bind(&Watchdog::handleTimerTick, this));
+ timer = timerFactory->createTimer(nextTimeout);
+ timer->onTick.connect(boost::bind(&Watchdog::handleTimerTick, this));
+ }
+ remainingTime -= nextTimeout;
+ timer->start();
+ }
+}
diff --git a/Sluift/Watchdog.h b/Sluift/Watchdog.h
index 95b6971..868621e 100644
--- a/Sluift/Watchdog.h
+++ b/Sluift/Watchdog.h
@@ -1,44 +1,32 @@
/*
- * Copyright (c) 2011 Remko Tronçon
+ * Copyright (c) 2011-2014 Remko Tronçon
* Licensed under the GNU General Public License v3.
* See Documentation/Licenses/GPLv3.txt for more information.
*/
#pragma once
+#include <algorithm>
+
#include <Swiften/Network/TimerFactory.h>
namespace Swift {
class Watchdog {
public:
- Watchdog(int timeout, TimerFactory* timerFactory) : timedOut(false) {
- if (timeout > 0) {
- timer = timerFactory->createTimer(timeout);
- timer->start();
- timer->onTick.connect(boost::bind(&Watchdog::handleTimerTick, this));
- }
- else if (timeout == 0) {
- timedOut = true;
- }
- }
-
- ~Watchdog() {
- if (timer) {
- timer->stop();
- }
- }
+ Watchdog(int timeout, TimerFactory* timerFactory);
+ ~Watchdog();
bool getTimedOut() const {
return timedOut;
}
private:
- void handleTimerTick() {
- timedOut = true;
- }
+ void handleTimerTick();
private:
Timer::ref timer;
+ int remainingTime;
+ TimerFactory* timerFactory;
bool timedOut;
};
}
diff --git a/Sluift/client.cpp b/Sluift/client.cpp
index 16f1281..9cb5090 100644
--- a/Sluift/client.cpp
+++ b/Sluift/client.cpp
@@ -25,7 +25,6 @@
#include <Swiften/Roster/SetRosterRequest.h>
#include <Swiften/Presence/SubscriptionManager.h>
#include <Swiften/Roster/XMPPRosterItem.h>
-#include <Sluift/Watchdog.h>
#include <Swiften/Queries/Requests/GetSoftwareVersionRequest.h>
#include <Sluift/Lua/FunctionRegistration.h>
#include <Swiften/Base/foreach.h>
diff --git a/Sluift/main.cpp b/Sluift/main.cpp
index 76ba572..505cc5c 100644
--- a/Sluift/main.cpp
+++ b/Sluift/main.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2013 Remko Tronçon
+ * Copyright (c) 2013-2014 Remko Tronçon
* Licensed under the GNU General Public License.
* See the COPYING file for more information.
*/
@@ -15,6 +15,7 @@
#include <boost/version.hpp>
#include <boost/numeric/conversion/cast.hpp>
#include <boost/assign/list_of.hpp>
+#include <Sluift/globals.h>
#include <Sluift/Console.h>
#include <Sluift/StandardTerminal.h>
#include <Sluift/sluift.h>
@@ -48,6 +49,10 @@ static const luaL_Reg defaultLibraries[] = {
{NULL, NULL}
};
+static void handleInterruptSignal(int) {
+ Sluift::globals.interruptRequested = 1;
+}
+
static void checkResult(lua_State* L, int result) {
if (result && !lua_isnil(L, -1)) {
const char* errorMessage = lua_tostring(L, -1);
@@ -150,6 +155,9 @@ int main(int argc, char* argv[]) {
// Run console
if (arguments.count("interactive") || arguments.count("script") == 0) {
+ // Set up signal handler
+ signal(SIGINT, handleInterruptSignal);
+
// Import some useful functions into the global namespace
lua_getglobal(L, "sluift");
std::vector<std::string> globalImports = boost::assign::list_of