From 5163b1a6241882a3d45cda053daae182de0ebf5d Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Sat, 7 Jan 2017 16:01:58 +0100 Subject: [PATCH] lib/curl/Request: require the caller to explicitly register the request This allows constructing an instance in any thread, and register it inside the IOThread later. --- src/input/plugins/CurlInputPlugin.cxx | 2 ++ src/lib/curl/Request.cxx | 25 ++++++++++++++++++++++--- src/lib/curl/Request.hxx | 20 ++++++++++++++++++++ 3 files changed, 44 insertions(+), 3 deletions(-) diff --git a/src/input/plugins/CurlInputPlugin.cxx b/src/input/plugins/CurlInputPlugin.cxx index b6208361d..0789cac3a 100644 --- a/src/input/plugins/CurlInputPlugin.cxx +++ b/src/input/plugins/CurlInputPlugin.cxx @@ -373,6 +373,8 @@ CurlInputStream::InitEasy() request_headers.Clear(); request_headers.Append("Icy-Metadata: 1"); request->SetOption(CURLOPT_HTTPHEADER, request_headers.Get()); + + request->Start(); } void diff --git a/src/lib/curl/Request.cxx b/src/lib/curl/Request.cxx index 4b197221e..2af6ba881 100644 --- a/src/lib/curl/Request.cxx +++ b/src/lib/curl/Request.cxx @@ -62,8 +62,6 @@ CurlRequest::CurlRequest(CurlGlobal &_global, const char *url, easy.SetOption(CURLOPT_NOSIGNAL, 1l); easy.SetOption(CURLOPT_CONNECTTIMEOUT, 10l); easy.SetOption(CURLOPT_URL, url); - - global.Add(easy.Get(), *this); } CurlRequest::~CurlRequest() @@ -71,19 +69,40 @@ CurlRequest::~CurlRequest() FreeEasy(); } +void +CurlRequest::Start() +{ + assert(!registered); + + global.Add(easy.Get(), *this); + registered = true; +} + +void +CurlRequest::Stop() +{ + assert(registered); + + global.Remove(easy.Get()); + registered = false; +} + void CurlRequest::FreeEasy() { if (!easy) return; - global.Remove(easy.Get()); + if (registered) + Stop(); easy = nullptr; } void CurlRequest::Resume() { + assert(registered); + curl_easy_pause(easy.Get(), CURLPAUSE_CONT); if (IsCurlOlderThan(0x072000)) diff --git a/src/lib/curl/Request.hxx b/src/lib/curl/Request.hxx index 2a5c55d0a..5a6428db1 100644 --- a/src/lib/curl/Request.hxx +++ b/src/lib/curl/Request.hxx @@ -58,7 +58,12 @@ class CurlRequest { /** error message provided by libcurl */ char error_buffer[CURL_ERROR_SIZE]; + bool registered = false; + public: + /** + * To start sending the request, call Start(). + */ CurlRequest(CurlGlobal &_global, const char *url, CurlResponseHandler &_handler); ~CurlRequest(); @@ -66,6 +71,21 @@ public: CurlRequest(const CurlRequest &) = delete; CurlRequest &operator=(const CurlRequest &) = delete; + /** + * Register this request via CurlGlobal::Add(), which starts + * the request. + * + * This method must be called in the event loop thread. + */ + void Start(); + + /** + * Unregister this request via CurlGlobal::Remove(). + * + * This method must be called in the event loop thread. + */ + void Stop(); + CURL *Get() { return easy.Get(); }