void DllLibCurlGlobal::CheckIdle() { CSingleLock lock(m_critSection); /* 20 seconds idle time before closing handle */ const unsigned int idletime = 30000; VEC_CURLSESSIONS::iterator it = m_sessions.begin(); while (it != m_sessions.end()) { if (!it->m_busy && (XbmcThreads::SystemClockMillis() - it->m_idletimestamp) > idletime) { CLog::Log(LOGINFO, "%s - Closing session to %s://%s (easy=%p, multi=%p)\n", __FUNCTION__, it->m_protocol.c_str(), it->m_hostname.c_str(), static_cast<void*>(it->m_easy), static_cast<void*>(it->m_multi)); if (it->m_multi && it->m_easy) multi_remove_handle(it->m_multi, it->m_easy); if (it->m_easy) easy_cleanup(it->m_easy); if (it->m_multi) multi_cleanup(it->m_multi); it = m_sessions.erase(it); continue; } ++it; } }
void cleanup_curl_handle(churl_context* context) { if (!context->curl_handle) return; if (context->multi_handle) multi_remove_handle(context); curl_easy_cleanup(context->curl_handle); context->curl_handle = NULL; curl_multi_cleanup(context->multi_handle); context->multi_handle = NULL; }
void churl_download_restart(CHURL_HANDLE handle, const char* url, CHURL_HEADERS headers) { churl_context* context = (churl_context*)handle; Assert(!context->upload); /* halt current transfer */ multi_remove_handle(context); /* set a new url */ set_curl_option(context, CURLOPT_URL, url); /* set headers again */ if (headers) churl_headers_set(context, headers); /* restart */ setup_multi_handle(context); }
int test(char *URL) { CURL *easy = NULL; CURLM *multi = NULL; int res = 0; int running; int msgs_left; int phase; CURLMsg *msg; start_test_timing(); res_global_init(CURL_GLOBAL_ALL); if(res) { return res; } easy_init(easy); multi_init(multi); for (phase = CONNECT_ONLY_PHASE; phase < LAST_PHASE; ++phase) { /* go verbose */ easy_setopt(easy, CURLOPT_VERBOSE, 1L); /* specify target */ easy_setopt(easy, CURLOPT_URL, URL); /* enable 'CONNECT_ONLY' option when in connect phase */ if (phase == CONNECT_ONLY_PHASE) easy_setopt(easy, CURLOPT_CONNECT_ONLY, 1L); /* enable 'NOBODY' option to send 'QUIT' command in quit phase */ if (phase == QUIT_PHASE) { easy_setopt(easy, CURLOPT_CONNECT_ONLY, 0L); easy_setopt(easy, CURLOPT_NOBODY, 1L); easy_setopt(easy, CURLOPT_FORBID_REUSE, 1L); } multi_add_handle(multi, easy); for(;;) { struct timeval interval; fd_set fdread; fd_set fdwrite; fd_set fdexcep; long timeout = -99; int maxfd = -99; multi_perform(multi, &running); abort_on_test_timeout(); if(!running) break; /* done */ FD_ZERO(&fdread); FD_ZERO(&fdwrite); FD_ZERO(&fdexcep); multi_fdset(multi, &fdread, &fdwrite, &fdexcep, &maxfd); /* At this point, maxfd is guaranteed to be greater or equal than -1. */ multi_timeout(multi, &timeout); /* At this point, timeout is guaranteed to be greater or equal than -1. */ if(timeout != -1L) { int itimeout = (timeout > (long)INT_MAX) ? INT_MAX : (int)timeout; interval.tv_sec = itimeout/1000; interval.tv_usec = (itimeout%1000)*1000; } else { interval.tv_sec = TEST_HANG_TIMEOUT/1000+1; interval.tv_usec = 0; } select_test(maxfd+1, &fdread, &fdwrite, &fdexcep, &interval); abort_on_test_timeout(); } msg = curl_multi_info_read(multi, &msgs_left); if(msg) res = msg->data.result; multi_remove_handle(multi, easy); } test_cleanup: /* undocumented cleanup sequence - type UA */ curl_multi_cleanup(multi); curl_easy_cleanup(easy); curl_global_cleanup(); return res; }