diff options
-rw-r--r-- | includes/CurlTask.h | 15 | ||||
-rw-r--r-- | includes/LuaTask.h | 3 | ||||
-rw-r--r-- | includes/TaskMan.h | 9 | ||||
-rw-r--r-- | includes/c++11-surrogates.h | 21 | ||||
-rw-r--r-- | src/TaskMan.cc | 97 | ||||
-rw-r--r-- | win32/project/Balau.vcxproj | 2 | ||||
-rw-r--r-- | win32/project/Balau.vcxproj.filters | 6 |
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">
|