From e3c2cf74256daf8131f39631d349a9fa9cacacc2 Mon Sep 17 00:00:00 2001 From: "Nicolas \"Pixel\" Noble" Date: Wed, 18 Jun 2014 17:33:35 -0700 Subject: Adding basic CurlTask, as well as support for it in Balau. Also removing c++11-surrogates.h, as we're on a modern compiler now. --- includes/CurlTask.h | 15 ++++++ includes/LuaTask.h | 3 +- includes/TaskMan.h | 9 +++- includes/c++11-surrogates.h | 21 -------- src/TaskMan.cc | 97 ++++++++++++++++++++++++++++++++----- win32/project/Balau.vcxproj | 2 +- win32/project/Balau.vcxproj.filters | 6 +-- 7 files changed, 111 insertions(+), 42 deletions(-) create mode 100644 includes/CurlTask.h delete mode 100644 includes/c++11-surrogates.h 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 +#include +#include + +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 #include #include #include @@ -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 struct RemoveReference { - typedef T type; -}; - -template struct RemoveReference { - typedef T type; -}; - -template struct RemoveReference { - typedef T type; -}; - -template typename RemoveReference::type&& Move(T&& t) { - return static_cast::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 @@ -223,6 +224,85 @@ Balau::TaskMan::TaskMan() { m_nStacks = 0; m_curlMulti = curl_multi_init(); + + curl_multi_setopt(m_curlMulti, CURLMOPT_SOCKETFUNCTION, reinterpret_cast(curlSocketCallbackStatic)); + curl_multi_setopt(m_curlMulti, CURLMOPT_SOCKETDATA, this); + curl_multi_setopt(m_curlMulti, CURLMOPT_TIMERFUNCTION, reinterpret_cast (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(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(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(curlSocketCallback)); - curl_multi_setopt(m_curlMulti, CURLMOPT_SOCKETDATA, this); - curl_multi_setopt(m_curlMulti, CURLMOPT_TIMERFUNCTION, reinterpret_cast (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(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 @@ - + 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 @@ Headers - - Headers - Headers @@ -332,6 +329,9 @@ Headers + + Headers + -- cgit v1.2.3