diff --git a/include/wx/webrequest_curl.h b/include/wx/webrequest_curl.h index 45f34611e2..d2cef8ad54 100644 --- a/include/wx/webrequest_curl.h +++ b/include/wx/webrequest_curl.h @@ -13,6 +13,7 @@ #if wxUSE_WEBREQUEST_CURL #include "wx/thread.h" +#include "wx/vector.h" #include "curl/curl.h" @@ -117,6 +118,8 @@ public: bool StartRequest(wxWebRequestCURL& request); + void CancelRequest(wxWebRequestCURL* request); + protected: wxThread::ExitCode Entry() wxOVERRIDE; @@ -125,6 +128,8 @@ private: wxCondition m_condition; wxMutex m_mutex; bool m_shuttingDown; + wxMutex m_cancelledMutex; + wxVector< wxObjectDataPtr > m_cancelledRequests; void Initialize(); diff --git a/src/common/webrequest_curl.cpp b/src/common/webrequest_curl.cpp index 5c1a295c92..b4dbc00c89 100644 --- a/src/common/webrequest_curl.cpp +++ b/src/common/webrequest_curl.cpp @@ -243,7 +243,7 @@ bool wxWebRequestCURL::StartRequest() void wxWebRequestCURL::Cancel() { - wxFAIL_MSG("not implemented"); + static_cast(GetSession()).CancelRequest(this); } void wxWebRequestCURL::HandleCompletion() @@ -393,6 +393,18 @@ wxThread::ExitCode wxWebSessionCURL::Entry() while ( activeRequests ) { + // Handle cancelled requests + { + wxMutexLocker lock(m_cancelledMutex); + while ( !m_cancelledRequests.empty() ) + { + wxObjectDataPtr request(m_cancelledRequests.back()); + m_cancelledRequests.pop_back(); + curl_multi_remove_handle(m_handle, request->GetHandle()); + request->SetState(wxWebRequest::State_Cancelled); + } + } + // Instruct CURL to work on requests curl_multi_perform(m_handle, &activeRequests); @@ -413,7 +425,7 @@ wxThread::ExitCode wxWebSessionCURL::Entry() { // Wait for CURL work to finish int numfds; - curl_multi_wait(m_handle, NULL, 0, 1000, &numfds); + curl_multi_wait(m_handle, NULL, 0, 500, &numfds); if ( !numfds ) { @@ -458,6 +470,15 @@ bool wxWebSessionCURL::StartRequest(wxWebRequestCURL & request) return true; } +void wxWebSessionCURL::CancelRequest(wxWebRequestCURL* request) +{ + // Add the request to a list of threads that will be removed from the curl + // multi handle in the worker thread + wxMutexLocker lock(m_cancelledMutex); + request->IncRef(); + m_cancelledRequests.push_back(wxObjectDataPtr(request)); +} + // static void wxWebSessionCURL::InitializeCURL() {