summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--includes/CurlTask.h15
-rw-r--r--includes/LuaTask.h3
-rw-r--r--includes/TaskMan.h9
-rw-r--r--includes/c++11-surrogates.h21
-rw-r--r--src/TaskMan.cc97
-rw-r--r--win32/project/Balau.vcxproj2
-rw-r--r--win32/project/Balau.vcxproj.filters6
7 files changed, 111 insertions, 42 deletions
diff --git a/includes/CurlTask.h b/includes/CurlTask.h
new file mode 100644
index 0000000..f9ac492
--- /dev/null
+++ b/includes/CurlTask.h
@@ -0,0 +1,15 @@
+#pragma once
+
+#include <curl/curl.h>
+#include <Task.h>
+#include <TaskMan.h>
+
+namespace Balau {
+
+class CurlTask : public Task {
+ friend class TaskMan;
+ protected:
+ CURL * m_curlHandle;
+};
+
+};
diff --git a/includes/LuaTask.h b/includes/LuaTask.h
index a12f89f..e3dfe1c 100644
--- a/includes/LuaTask.h
+++ b/includes/LuaTask.h
@@ -1,6 +1,5 @@
#pragma once
-#include <c++11-surrogates.h>
#include <BLua.h>
#include <Task.h>
#include <StacklessTask.h>
@@ -58,7 +57,7 @@ class LuaTask : public Task {
~LuaTask() { L.weaken(); }
virtual const char * getName() const { return "LuaTask"; }
private:
- LuaTask(Lua && __L, LuaExecCell * cell) : L(Move(__L)), m_cell(cell) { if (!cell->needsStack()) setStackless(); }
+ LuaTask(Lua && __L, LuaExecCell * cell) : L(std::move(__L)), m_cell(cell) { if (!cell->needsStack()) setStackless(); }
virtual void Do();
Lua L;
LuaExecCell * m_cell;
diff --git a/includes/TaskMan.h b/includes/TaskMan.h
index a9eb490..a51653b 100644
--- a/includes/TaskMan.h
+++ b/includes/TaskMan.h
@@ -103,10 +103,15 @@ class TaskMan {
int m_stopCode = 0;
bool m_stopped = false;
bool m_allowedToSignal = false;
+ ev::timer m_curlTimer;
CURLM * m_curlMulti = false;
int m_curlStillRunning = 0;
- static int curlSocketCallback(CURL * easy, curl_socket_t s, int what, void * userp, void * socketp);
- static int curlMultiTimerCallback(CURLM * multi, long timeout_ms, void * userp);
+ static int curlSocketCallbackStatic(CURL * easy, curl_socket_t s, int what, void * userp, void * socketp);
+ int curlSocketCallback(CURL * easy, curl_socket_t s, int what, void * socketp);
+ void curlSocketEventCallback(ev::io & w, int revents);
+ static int curlMultiTimerCallbackStatic(CURLM * multi, long timeout_ms, void * userp);
+ int curlMultiTimerCallback(CURLM * multi, long timeout_ms);
+ void curlMultiTimerEventCallback(ev::timer & w, int revents);
TaskMan(const TaskMan &) = delete;
TaskMan & operator=(const TaskMan &) = delete;
diff --git a/includes/c++11-surrogates.h b/includes/c++11-surrogates.h
deleted file mode 100644
index 4f3a1a0..0000000
--- a/includes/c++11-surrogates.h
+++ /dev/null
@@ -1,21 +0,0 @@
-#pragma once
-
-namespace Balau {
-
-template <typename T> struct RemoveReference {
- typedef T type;
-};
-
-template <typename T> struct RemoveReference<T&> {
- typedef T type;
-};
-
-template <typename T> struct RemoveReference<T&&> {
- typedef T type;
-};
-
-template <typename T> typename RemoveReference<T>::type&& Move(T&& t) {
- return static_cast<typename RemoveReference<T>::type&&>(t);
-}
-
-};
diff --git a/src/TaskMan.cc b/src/TaskMan.cc
index c50e57a..ae3757c 100644
--- a/src/TaskMan.cc
+++ b/src/TaskMan.cc
@@ -4,6 +4,7 @@
#include "Task.h"
#include "Main.h"
#include "Local.h"
+#include "CurlTask.h"
#ifdef _MSC_VER
#include <Windows.h>
@@ -223,6 +224,85 @@ Balau::TaskMan::TaskMan() {
m_nStacks = 0;
m_curlMulti = curl_multi_init();
+
+ curl_multi_setopt(m_curlMulti, CURLMOPT_SOCKETFUNCTION, reinterpret_cast<curl_socket_callback>(curlSocketCallbackStatic));
+ curl_multi_setopt(m_curlMulti, CURLMOPT_SOCKETDATA, this);
+ curl_multi_setopt(m_curlMulti, CURLMOPT_TIMERFUNCTION, reinterpret_cast <curl_multi_timer_callback>(curlMultiTimerCallbackStatic));
+ curl_multi_setopt(m_curlMulti, CURLMOPT_TIMERDATA, this);
+ curl_multi_setopt(m_curlMulti, CURLMOPT_PIPELINING, 1L);
+
+ m_curlTimer.set(m_loop);
+ m_curlTimer.set<TaskMan, &TaskMan::curlMultiTimerEventCallback>(this);
+}
+
+int Balau::TaskMan::curlSocketCallbackStatic(CURL * easy, curl_socket_t s, int what, void * userp, void * socketp) {
+ TaskMan * taskMan = (TaskMan *)userp;
+ return taskMan->curlSocketCallback(easy, s, what, socketp);
+}
+
+int Balau::TaskMan::curlSocketCallback(CURL * easy, curl_socket_t s, int what, void * socketp) {
+ ev::io * evt = (ev::io *) socketp;
+ if (!evt) {
+ if (what == CURL_POLL_REMOVE)
+ return 0;
+ evt = new ev::io;
+ evt->set<TaskMan, &TaskMan::curlSocketEventCallback>(this);
+ evt->set(s, ev::READ | ev::WRITE);
+ evt->set(m_loop);
+ evt->start();
+ curl_multi_assign(m_curlMulti, s, evt);
+ }
+
+ switch (what) {
+ case CURL_POLL_NONE:
+ evt->stop();
+ break;
+ case CURL_POLL_IN:
+ evt->set(s, ev::READ);
+ evt->start();
+ break;
+ case CURL_POLL_OUT:
+ evt->set(s, ev::WRITE);
+ evt->start();
+ break;
+ case CURL_POLL_INOUT:
+ evt->set(s, ev::READ | ev::WRITE);
+ evt->start();
+ break;
+ case CURL_POLL_REMOVE:
+ evt->stop();
+ curl_multi_assign(m_curlMulti, s, NULL);
+ delete evt;
+ }
+
+ return 0;
+}
+
+void Balau::TaskMan::curlSocketEventCallback(ev::io & w, int revents) {
+ int bitmask = 0;
+ if (revents & ev::READ)
+ bitmask |= CURL_POLL_IN;
+ if (revents & ev::WRITE)
+ bitmask |= CURL_POLL_OUT;
+ curl_multi_socket_action(m_curlMulti, w.fd, bitmask, &m_curlStillRunning);
+}
+
+int Balau::TaskMan::curlMultiTimerCallbackStatic(CURLM * multi, long timeout_ms, void * userp) {
+ TaskMan * taskMan = (TaskMan *)userp;
+ return taskMan->curlMultiTimerCallback(multi, timeout_ms);
+}
+
+int Balau::TaskMan::curlMultiTimerCallback(CURLM * multi, long timeout_ms) {
+ m_curlTimer.stop();
+ if (timeout_ms >= 0) {
+ m_curlTimer.set((ev_tstamp) timeout_ms);
+ m_curlTimer.start();
+ }
+ return 0;
+}
+
+void Balau::TaskMan::curlMultiTimerEventCallback(ev::timer & w, int revents) {
+ curl_multi_socket_action(m_curlMulti, CURL_SOCKET_TIMEOUT, 0, &m_curlStillRunning);
}
#ifdef _WIN32
@@ -256,19 +336,6 @@ Balau::TaskMan::~TaskMan() {
m_evt.stop();
ev_loop_destroy(m_loop);
curl_multi_cleanup(m_curlMulti);
- curl_multi_setopt(m_curlMulti, CURLMOPT_SOCKETFUNCTION, reinterpret_cast<curl_socket_callback>(curlSocketCallback));
- curl_multi_setopt(m_curlMulti, CURLMOPT_SOCKETDATA, this);
- curl_multi_setopt(m_curlMulti, CURLMOPT_TIMERFUNCTION, reinterpret_cast <curl_multi_timer_callback>(curlMultiTimerCallback));
- curl_multi_setopt(m_curlMulti, CURLMOPT_TIMERDATA, this);
- curl_multi_setopt(m_curlMulti, CURLMOPT_PIPELINING, 1L);
-}
-
-int Balau::TaskMan::curlSocketCallback(CURL * easy, curl_socket_t s, int what, void * userp, void * socketp) {
- return 0;
-}
-
-int Balau::TaskMan::curlMultiTimerCallback(CURLM * multi, long timeout_ms, void * userp) {
- return 0;
}
void * Balau::TaskMan::getStack() {
@@ -390,6 +457,10 @@ int Balau::TaskMan::mainLoop() {
t->setup(this, t->isStackless() ? NULL : getStack());
m_tasks.insert(t);
starting.insert(t);
+ CurlTask * curlTask = dynamic_cast<CurlTask *>(t);
+ if (curlTask) {
+ curl_multi_add_handle(m_curlMulti, curlTask->m_curlHandle);
+ }
}
// Finally, let's destroy tasks that no longer are necessary.
diff --git a/win32/project/Balau.vcxproj b/win32/project/Balau.vcxproj
index c0b82de..f50aac4 100644
--- a/win32/project/Balau.vcxproj
+++ b/win32/project/Balau.vcxproj
@@ -270,7 +270,7 @@
<ClInclude Include="..\..\includes\BString.h" />
<ClInclude Include="..\..\includes\Buffer.h" />
<ClInclude Include="..\..\includes\BWebSocket.h" />
- <ClInclude Include="..\..\includes\c++11-surrogates.h" />
+ <ClInclude Include="..\..\includes\CurlTask.h" />
<ClInclude Include="..\..\includes\Exceptions.h" />
<ClInclude Include="..\..\includes\Handle.h" />
<ClInclude Include="..\..\includes\HelperTasks.h" />
diff --git a/win32/project/Balau.vcxproj.filters b/win32/project/Balau.vcxproj.filters
index bd79687..2742441 100644
--- a/win32/project/Balau.vcxproj.filters
+++ b/win32/project/Balau.vcxproj.filters
@@ -209,9 +209,6 @@
<ClInclude Include="..\..\includes\BWebSocket.h">
<Filter>Headers</Filter>
</ClInclude>
- <ClInclude Include="..\..\includes\c++11-surrogates.h">
- <Filter>Headers</Filter>
- </ClInclude>
<ClInclude Include="..\..\includes\Exceptions.h">
<Filter>Headers</Filter>
</ClInclude>
@@ -332,6 +329,9 @@
<ClInclude Include="..\..\includes\MMap.h">
<Filter>Headers</Filter>
</ClInclude>
+ <ClInclude Include="..\..\includes\CurlTask.h">
+ <Filter>Headers</Filter>
+ </ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="..\..\src\jsoncpp\src\json_internalarray.inl">