Work on cURL Multi

This commit is contained in:
Joshua Granick
2018-06-21 12:41:23 -07:00
parent 23caa4d36a
commit c67d3562c5
5 changed files with 286 additions and 149 deletions

View File

@@ -32,7 +32,8 @@ namespace lime {
};
std::map<void*, CURLM*> curlMultiHandles;
std::map<void*, std::vector<void*>* > curlMultiHandles;
std::map<void*, void*> curlMultiReferences;
std::map<void*, int> curlMultiRunningHandles;
std::map<void*, bool> curlMultiValid;
std::map<CURL*, void*> curlObjects;
@@ -60,11 +61,11 @@ namespace lime {
curl_gc_mutex.Lock ();
if (curlMultiHandles.find (handle) != curlMultiHandles.end ()) {
if (curlMultiReferences.find (handle) != curlMultiReferences.end ()) {
CURLM* multi = curlMultiHandles[handle];
curl_multi_remove_handle (multi, handle);
curlMultiHandles.erase (handle);
value multi_handle = (value)curlMultiReferences[handle];
curl_multi_remove_handle ((CURLM*)val_data (multi_handle), handle);
curlMultiReferences.erase (handle);
}
@@ -164,11 +165,11 @@ namespace lime {
curl_gc_mutex.Lock ();
if (curlMultiHandles.find (handle) != curlMultiHandles.end ()) {
if (curlMultiReferences.find (handle) != curlMultiReferences.end ()) {
CURLM* multi = curlMultiHandles[handle];
curl_multi_remove_handle (multi, handle);
curlMultiHandles.erase (handle);
HL_CFFIPointer* multi_handle = (HL_CFFIPointer*)curlMultiReferences[handle];
curl_multi_remove_handle ((CURLM*)multi_handle->ptr, handle);
curlMultiReferences.erase (handle);
}
@@ -273,16 +274,19 @@ namespace lime {
}
for (std::map<void*, void*>::iterator it = curlMultiHandles.begin (); it != curlMultiHandles.end (); ++it) {
std::vector<void*>* handles = curlMultiHandles[handle];
for (std::vector<void*>::iterator it = handles->begin (); it != handles->end (); ++it) {
if (curlMultiHandles[it->first] == handle) {
gc_curl ((value)it->first);
}
curl_gc_mutex.Unlock ();
gc_curl ((value)*it);
curl_gc_mutex.Lock ();
}
delete curlMultiHandles[handle];
curlMultiHandles.erase (handle);
val_gc (handle, 0);
//handle = alloc_null ();
@@ -306,16 +310,19 @@ namespace lime {
}
for (std::map<void*, void*>::iterator it = curlMultiHandles.begin (); it != curlMultiHandles.end (); ++it) {
std::vector<void*>* handles = curlMultiHandles[handle];
for (std::vector<void*>::iterator it = handles->begin (); it != handles->end (); ++it) {
if (curlMultiHandles[it->first] == handle) {
hl_gc_curl ((HL_CFFIPointer*)it->first);
}
curl_gc_mutex.Unlock ();
hl_gc_curl ((HL_CFFIPointer*)*it);
curl_gc_mutex.Lock ();
}
delete curlMultiHandles[handle];
curlMultiHandles.erase (handle);
handle->finalizer = NULL;
//handle = alloc_null ();
@@ -497,7 +504,9 @@ namespace lime {
for (std::vector<char*>::iterator it = values->begin (); it != values->end (); ++it) {
curl_gc_mutex.Unlock ();
headerCallback->Call (alloc_string (*it));
curl_gc_mutex.Lock ();
}
@@ -524,7 +533,9 @@ namespace lime {
buffer->sputn ((char*)bytes->b, length);
buffer->str ("");
curl_gc_mutex.Unlock ();
length = val_int ((value)writeCallback->Call (bytes->Value ((value)bytesRoot->Get ())));
curl_gc_mutex.Lock ();
if (length == CURL_WRITEFUNC_PAUSE) {
@@ -543,7 +554,9 @@ namespace lime {
CURL_Progress* progress = progressValues[easy_handle];
ValuePointer* progressCallback = progressCallbacks[easy_handle];
curl_gc_mutex.Unlock ();
code = val_int ((value)progressCallback->Call (alloc_float (progress->dltotal), alloc_float (progress->dlnow), alloc_float (progress->ultotal), alloc_float (progress->ulnow)));
curl_gc_mutex.Lock ();
if (code != 0) { // CURLE_OK
@@ -558,7 +571,9 @@ namespace lime {
CURL_XferInfo* xferInfo = xferInfoValues[easy_handle];
ValuePointer* xferInfoCallback = xferInfoCallbacks[easy_handle];
curl_gc_mutex.Unlock ();
code = val_int ((value)xferInfoCallback->Call (alloc_int (xferInfo->dltotal), alloc_int (xferInfo->dlnow), alloc_int (xferInfo->ultotal), alloc_int (xferInfo->ulnow)));
curl_gc_mutex.Lock ();
if (code != 0) {
@@ -568,6 +583,8 @@ namespace lime {
}
curl_gc_mutex.Unlock ();
}
@@ -588,7 +605,9 @@ namespace lime {
vdynamic* bytes = hl_alloc_dynamic (&hlt_bytes);
bytes->v.bytes = (vbyte*)*it;
curl_gc_mutex.Unlock ();
headerCallback->Call (bytes);
curl_gc_mutex.Lock ();
}
@@ -614,7 +633,9 @@ namespace lime {
buffer->sputn ((char*)bytes->b, length);
buffer->str ("");
curl_gc_mutex.Unlock ();
length = (int)writeCallback->Call (bytes);
curl_gc_mutex.Lock ();
if (length == CURL_WRITEFUNC_PAUSE) {
@@ -643,7 +664,9 @@ namespace lime {
ultotal->v.d = progress->ultotal;
ulnow->v.d = progress->ulnow;
curl_gc_mutex.Unlock ();
code = (int)progressCallback->Call (dltotal, dlnow, ultotal, ulnow);
curl_gc_mutex.Lock ();
if (code != 0) { // CURLE_OK
@@ -668,7 +691,9 @@ namespace lime {
ultotal->v.i = xferInfo->ultotal;
ulnow->v.i = xferInfo->ulnow;
curl_gc_mutex.Unlock ();
code = (int)xferInfoCallback->Call (dltotal, dlnow, ultotal, ulnow);
curl_gc_mutex.Lock ();
if (code != 0) {
@@ -678,6 +703,8 @@ namespace lime {
}
curl_gc_mutex.Unlock ();
}
@@ -2119,12 +2146,12 @@ namespace lime {
int lime_curl_multi_cleanup (value multi_handle) {
curl_gc_mutex.Lock ();
// curl_gc_mutex.Lock ();
// CURLMcode result = curl_multi_cleanup ((CURLM*)val_data (multi_handle));
gc_curl_multi (multi_handle);
curl_gc_mutex.Unlock ();
// curl_gc_mutex.Unlock ();
return CURLM_OK;
@@ -2133,12 +2160,12 @@ namespace lime {
HL_PRIM int hl_lime_curl_multi_cleanup (HL_CFFIPointer* multi_handle) {
curl_gc_mutex.Lock ();
// curl_gc_mutex.Lock ();
// CURLMcode result = curl_multi_cleanup ((CURLM*)val_data (multi_handle));
hl_gc_curl_multi (multi_handle);
curl_gc_mutex.Unlock ();
// curl_gc_mutex.Unlock ();
return CURLM_OK;
@@ -2159,6 +2186,7 @@ namespace lime {
curlMultiValid[handle] = true;
curlMultiRunningHandles[handle] = 0;
curlMultiHandles[handle] = new std::vector<void*> ();
curl_gc_mutex.Unlock ();
@@ -2181,6 +2209,7 @@ namespace lime {
curlMultiValid[handle] = true;
curlMultiRunningHandles[handle] = 0;
curlMultiHandles[handle] = new std::vector<void*> ();
curl_gc_mutex.Unlock ();
@@ -2197,7 +2226,8 @@ namespace lime {
if (result == CURLM_OK) {
curlMultiHandles[curl_handle] = multi_handle;
curlMultiReferences[curl_handle] = multi_handle;
curlMultiHandles[multi_handle]->push_back (curl_handle);
}
@@ -2216,7 +2246,8 @@ namespace lime {
if (result == CURLM_OK) {
curlMultiHandles[curl_handle] = multi_handle;
curlMultiReferences[curl_handle] = multi_handle;
curlMultiHandles[multi_handle]->push_back (curl_handle);
}
@@ -2321,6 +2352,16 @@ namespace lime {
int runningHandles = 0;
CURLMcode result = curl_multi_perform ((CURLM*)val_data (multi_handle), &runningHandles);
std::vector<void*>* handles = curlMultiHandles[multi_handle];
for (std::vector<void*>::iterator it = handles->begin (); it != handles->end (); ++it) {
curl_gc_mutex.Unlock ();
lime_curl_easy_flush ((value)*it);
curl_gc_mutex.Lock ();
}
curlMultiRunningHandles[multi_handle] = runningHandles;
curl_gc_mutex.Unlock ();
@@ -2337,6 +2378,16 @@ namespace lime {
int runningHandles = 0;
CURLMcode result = curl_multi_perform ((CURLM*)multi_handle->ptr, &runningHandles);
std::vector<void*>* handles = curlMultiHandles[multi_handle];
for (std::vector<void*>::iterator it = handles->begin (); it != handles->end (); ++it) {
curl_gc_mutex.Unlock ();
hl_lime_curl_easy_flush ((HL_CFFIPointer*)*it);
curl_gc_mutex.Lock ();
}
curlMultiRunningHandles[multi_handle] = runningHandles;
curl_gc_mutex.Unlock ();
@@ -2352,9 +2403,26 @@ namespace lime {
CURLMcode result = curl_multi_remove_handle ((CURLM*)val_data (multi_handle), (CURL*)val_data (curl_handle));
if (/*result == CURLM_OK &&*/ curlMultiHandles.find (curl_handle) != curlMultiHandles.end ()) {
if (/*result == CURLM_OK &&*/ curlMultiReferences.find (curl_handle) != curlMultiReferences.end ()) {
curlMultiHandles.erase (curl_handle);
curlMultiReferences.erase (curl_handle);
}
std::vector<void*>* handles = curlMultiHandles[multi_handle];
if (handles->size () > 0) {
for (std::vector<void*>::iterator it = handles->begin (); it != handles->end (); ++it) {
if (*it == curl_handle) {
handles->erase (it);
break;
}
}
}
@@ -2371,9 +2439,26 @@ namespace lime {
CURLMcode result = curl_multi_remove_handle ((CURLM*)multi_handle->ptr, (CURL*)curl_handle->ptr);
if (/*result == CURLM_OK &&*/ curlMultiHandles.find (curl_handle) != curlMultiHandles.end ()) {
if (/*result == CURLM_OK &&*/ curlMultiReferences.find (curl_handle) != curlMultiReferences.end ()) {
curlMultiHandles.erase (curl_handle);
curlMultiReferences.erase (curl_handle);
}
std::vector<void*>* handles = curlMultiHandles[multi_handle];
if (handles->size () > 0) {
for (std::vector<void*>::iterator it = handles->begin (); it != handles->end (); ++it) {
if (*it == curl_handle) {
handles->erase (it);
break;
}
}
}
@@ -2384,6 +2469,106 @@ namespace lime {
}
int lime_curl_multi_setopt (value multi_handle, int option, value parameter) {
CURLMcode code = CURLM_OK;
CURLM* multi = (CURLM*)val_data (multi_handle);
CURLMoption type = (CURLMoption)option;
switch (type) {
case CURLMOPT_PIPELINING:
code = curl_multi_setopt (multi, type, val_bool (parameter));
break;
case CURLMOPT_MAXCONNECTS:
case CURLMOPT_MAX_HOST_CONNECTIONS:
case CURLMOPT_MAX_PIPELINE_LENGTH:
case CURLMOPT_MAX_TOTAL_CONNECTIONS:
case CURLMOPT_CONTENT_LENGTH_PENALTY_SIZE:
case CURLMOPT_CHUNK_LENGTH_PENALTY_SIZE:
code = curl_multi_setopt (multi, type, val_int (parameter));
break;
case CURLMOPT_SOCKETFUNCTION:
case CURLMOPT_SOCKETDATA:
case CURLMOPT_TIMERFUNCTION:
case CURLMOPT_TIMERDATA:
case CURLMOPT_PUSHFUNCTION:
case CURLMOPT_PUSHDATA:
// TODO?
break;
case CURLMOPT_PIPELINING_SITE_BL:
case CURLMOPT_PIPELINING_SERVER_BL:
// TODO, array to slist
break;
default:
break;
}
return code;
}
HL_PRIM int hl_lime_curl_multi_setopt (HL_CFFIPointer* multi_handle, int option, vdynamic* parameter) {
CURLMcode code = CURLM_OK;
CURLM* multi = (CURLM*)multi_handle->ptr;
CURLMoption type = (CURLMoption)option;
switch (type) {
case CURLMOPT_PIPELINING:
code = curl_multi_setopt (multi, type, parameter->v.b);
break;
case CURLMOPT_MAXCONNECTS:
case CURLMOPT_MAX_HOST_CONNECTIONS:
case CURLMOPT_MAX_PIPELINE_LENGTH:
case CURLMOPT_MAX_TOTAL_CONNECTIONS:
case CURLMOPT_CONTENT_LENGTH_PENALTY_SIZE:
case CURLMOPT_CHUNK_LENGTH_PENALTY_SIZE:
code = curl_multi_setopt (multi, type, parameter->v.i);
break;
case CURLMOPT_SOCKETFUNCTION:
case CURLMOPT_SOCKETDATA:
case CURLMOPT_TIMERFUNCTION:
case CURLMOPT_TIMERDATA:
case CURLMOPT_PUSHFUNCTION:
case CURLMOPT_PUSHDATA:
// TODO?
break;
case CURLMOPT_PIPELINING_SITE_BL:
case CURLMOPT_PIPELINING_SERVER_BL:
// TODO, array to slist
break;
default:
break;
}
return code;
}
int lime_curl_multi_wait (value multi_handle, int timeout_ms) {
System::GCEnterBlocking ();
@@ -2495,6 +2680,7 @@ namespace lime {
DEFINE_PRIME1 (lime_curl_multi_info_read);
DEFINE_PRIME1 (lime_curl_multi_perform);
DEFINE_PRIME2 (lime_curl_multi_remove_handle);
DEFINE_PRIME3 (lime_curl_multi_setopt);
DEFINE_PRIME2 (lime_curl_multi_wait);
DEFINE_PRIME0 (lime_curl_version);
DEFINE_PRIME1 (lime_curl_version_info);
@@ -2527,6 +2713,7 @@ namespace lime {
DEFINE_HL_PRIM (_DYN, lime_curl_multi_info_read, _TCFFIPOINTER _DYN);
DEFINE_HL_PRIM (_I32, lime_curl_multi_perform, _TCFFIPOINTER);
DEFINE_HL_PRIM (_I32, lime_curl_multi_remove_handle, _TCFFIPOINTER _TCFFIPOINTER);
DEFINE_HL_PRIM (_I32, lime_curl_multi_setopt, _TCFFIPOINTER _I32 _DYN);
DEFINE_HL_PRIM (_I32, lime_curl_multi_wait, _TCFFIPOINTER _I32);
DEFINE_HL_PRIM (_BYTES, lime_curl_version, _NO_ARG);
DEFINE_HL_PRIM (_DYN, lime_curl_version_info, _I32);