From 55167abadfa1618a45a9f70cd27cc126468ab0c3 Mon Sep 17 00:00:00 2001 From: Joshua Granick Date: Tue, 12 Jun 2018 16:51:25 -0700 Subject: [PATCH] Update cURL with more work on cURL Multi --- lime/_backend/native/NativeCFFI.hx | 7 +++ lime/net/curl/CURLMsg.hx | 19 ++++++ lime/net/curl/CURLMulti.hx | 85 ++++++++++++++++++++++++++- project/src/backend/sdl/SDLSystem.cpp | 2 +- project/src/net/curl/CURLBindings.cpp | 78 ++++++++++++++++++++++-- 5 files changed, 184 insertions(+), 7 deletions(-) create mode 100644 lime/net/curl/CURLMsg.hx diff --git a/lime/_backend/native/NativeCFFI.hx b/lime/_backend/native/NativeCFFI.hx index e0cd80a48..c1f4e227a 100644 --- a/lime/_backend/native/NativeCFFI.hx +++ b/lime/_backend/native/NativeCFFI.hx @@ -847,6 +847,13 @@ class NativeCFFI { @:cffi private static function lime_curl_easy_setopt (handle:CFFIPointer, option:Int, parameter:Dynamic, writeBytes:Dynamic):Int; @:cffi private static function lime_curl_easy_strerror (errornum:Int):Dynamic; @:cffi private static function lime_curl_easy_unescape (curl:CFFIPointer, url:String, inlength:Int, outlength:Int):Dynamic; + @:cffi private static function lime_curl_multi_init ():CFFIPointer; + @:cffi private static function lime_curl_multi_add_handle (multi_handle:CFFIPointer, curl_handle:CFFIPointer):Int; + @:cffi private static function lime_curl_multi_get_running_handles (multi_handle:CFFIPointer):Int; + @:cffi private static function lime_curl_multi_info_read (multi_handle:CFFIPointer):Dynamic; + @:cffi private static function lime_curl_multi_perform (multi_handle:CFFIPointer):Int; + @:cffi private static function lime_curl_multi_remove_handle (multi_handle:CFFIPointer, curl_handle:CFFIPointer):Int; + @:cffi private static function lime_curl_multi_wait (multi_handle:CFFIPointer, timeout_ms:Int):Int; #end #if (lime_cffi && !macro && lime_opengl) diff --git a/lime/net/curl/CURLMsg.hx b/lime/net/curl/CURLMsg.hx new file mode 100644 index 000000000..195e946c7 --- /dev/null +++ b/lime/net/curl/CURLMsg.hx @@ -0,0 +1,19 @@ +package lime.net.curl; + + +class CURLMsg { + + + public var curl:CURL; + public var result:CURLCode; + + + private function new (curl:CURL, result:CURLCode) { + + this.curl = curl; + this.result = result; + + } + + +} \ No newline at end of file diff --git a/lime/net/curl/CURLMulti.hx b/lime/net/curl/CURLMulti.hx index cd1d7783a..cabf389ad 100644 --- a/lime/net/curl/CURLMulti.hx +++ b/lime/net/curl/CURLMulti.hx @@ -1,7 +1,6 @@ package lime.net.curl; -import haxe.io.Bytes; import lime._backend.native.NativeCFFI; import lime.system.CFFIPointer; @@ -11,11 +10,15 @@ import lime.system.CFFIPointer; #end @:access(lime._backend.native.NativeCFFI) +@:access(lime.net.curl.CURL) +@:access(lime.net.curl.CURLMsg) class CURLMulti { + public var runningHandles (get, never):Int; + private var handle:CFFIPointer; @@ -36,4 +39,84 @@ class CURLMulti { } + public function addHandle (curl:CURL):CURLMultiCode { + + #if (lime_cffi && lime_curl && !macro) + return cast NativeCFFI.lime_curl_multi_add_handle (handle, curl.handle); + #else + return cast 0; + #end + + } + + + public function infoRead ():CURLMsg { + + #if (lime_cffi && lime_curl && !macro) + var msg:Dynamic = NativeCFFI.lime_curl_multi_info_read (handle); + var result = null; + + if (msg != null) { + result = new CURLMsg (msg.easy_handle, msg.result); + } + + return result; + #else + return null; + #end + + } + + + public function perform ():CURLMultiCode { + + #if (lime_cffi && lime_curl && !macro) + return cast NativeCFFI.lime_curl_multi_perform (handle); + #else + return cast 0; + #end + + } + + + public function removeHandle (curl:CURL):CURLMultiCode { + + #if (lime_cffi && lime_curl && !macro) + return cast NativeCFFI.lime_curl_multi_remove_handle (handle, curl.handle); + #else + return cast 0; + #end + + } + + + public function wait (timeoutMS:Int):CURLMultiCode { + + #if (lime_cffi && lime_curl && !macro) + return cast NativeCFFI.lime_curl_multi_wait (handle, timeoutMS); + #else + return cast 0; + #end + + } + + + + + // Get & Set Methods + + + + + private function get_runningHandles ():Int { + + #if (lime_cffi && lime_curl && !macro) + return NativeCFFI.lime_curl_multi_get_running_handles (handle); + #else + return 0; + #end + + } + + } \ No newline at end of file diff --git a/project/src/backend/sdl/SDLSystem.cpp b/project/src/backend/sdl/SDLSystem.cpp index 22db3f9e1..644a116b9 100644 --- a/project/src/backend/sdl/SDLSystem.cpp +++ b/project/src/backend/sdl/SDLSystem.cpp @@ -654,7 +654,7 @@ namespace lime { #else - read = ::fread (ptr, size, count, (FILE*)stream->handle); + nmem = ::fread (ptr, size, count, (FILE*)stream->handle); #endif diff --git a/project/src/net/curl/CURLBindings.cpp b/project/src/net/curl/CURLBindings.cpp index 848b70f5c..6878f6e83 100644 --- a/project/src/net/curl/CURLBindings.cpp +++ b/project/src/net/curl/CURLBindings.cpp @@ -13,6 +13,7 @@ namespace lime { std::map curlMultiHandles; std::map curlMultiRunningHandles; std::map curlMultiValid; + std::map curlObjects; std::map curlValid; std::map headerCallbacks; std::map headerSLists; @@ -40,8 +41,11 @@ namespace lime { if (curlValid.find (handle) != curlValid.end ()) { + CURL* curl = (CURL*)val_data (handle); + curlValid.erase (handle); - curl_easy_cleanup ((CURL*)val_data(handle)); + curlObjects.erase (curl); + curl_easy_cleanup (curl); } @@ -179,8 +183,10 @@ namespace lime { curl_gc_mutex.Lock (); - value duphandle = CFFIPointer (curl_easy_duphandle ((CURL*)val_data(handle)), gc_curl); + CURL* dup = curl_easy_duphandle ((CURL*)val_data(handle)); + value duphandle = CFFIPointer (dup, gc_curl); curlValid[duphandle] = true; + curlObjects[dup] = duphandle; AutoGCRoot* callback; Bytes* _writeBytes; @@ -329,7 +335,8 @@ namespace lime { curl_gc_mutex.Lock (); - value handle = CFFIPointer (curl_easy_init (), gc_curl); + CURL* curl = curl_easy_init (); + value handle = CFFIPointer (curl, gc_curl); if (curlValid.find (handle) != curlValid.end ()) { @@ -362,6 +369,7 @@ namespace lime { } curlValid[handle] = true; + curlObjects[curl] = handle; curl_gc_mutex.Unlock (); @@ -946,12 +954,56 @@ namespace lime { } + int lime_curl_multi_get_running_handles (value multi_handle) { + + return curlMultiRunningHandles[multi_handle]; + + } + + + value lime_curl_multi_info_read (value multi_handle) { + + int msgs_in_queue; + CURLMsg* msg = curl_multi_info_read ((CURLM*)val_data (multi_handle), &msgs_in_queue); + + if (msg) { + + //const field val_id ("msg"); + const field easy_handle = val_id ("easy_handle"); + const field _result = val_id ("result"); + + CURL* curl = msg->easy_handle; + value result = alloc_empty_object (); + + if (curlObjects.find (curl) != curlObjects.end ()) { + + alloc_field (result, easy_handle, curlObjects[curl]); + + } else { + + // TODO? + alloc_field (result, easy_handle, alloc_null ()); + + } + + alloc_field (result, _result, alloc_int (msg->data.result)); + return result; + + } else { + + return alloc_null (); + + } + + } + + int lime_curl_multi_perform (value multi_handle) { curl_gc_mutex.Lock (); int runningHandles = 0; - CURLMcode result = lime_curl_multi_perform ((CURLM*)val_data (multi_handle), &runningHandles); + CURLMcode result = curl_multi_perform ((CURLM*)val_data (multi_handle), &runningHandles); curlMultiRunningHandles[multi_handle] = runningHandles; @@ -981,6 +1033,19 @@ namespace lime { } + int lime_curl_multi_wait (value multi_handle, int timeout_ms) { + + gc_enter_blocking (); + + int retcode; + CURLMcode result = curl_multi_wait ((CURLM*)val_data (multi_handle), 0, 0, timeout_ms, &retcode); + + gc_exit_blocking (); + return result; + + } + + //lime_curl_multi_add_handle //lime_curl_multi_assign //lime_curl_multi_cleanup @@ -1041,8 +1106,11 @@ namespace lime { DEFINE_PRIME1 (lime_curl_global_init); DEFINE_PRIME0 (lime_curl_multi_init); DEFINE_PRIME2 (lime_curl_multi_add_handle); - DEFINE_PRIME2 (lime_curl_multi_perform); + DEFINE_PRIME1 (lime_curl_multi_get_running_handles); + DEFINE_PRIME1 (lime_curl_multi_perform); + DEFINE_PRIME1 (lime_curl_multi_info_read); DEFINE_PRIME2 (lime_curl_multi_remove_handle); + DEFINE_PRIME2 (lime_curl_multi_wait); DEFINE_PRIME0 (lime_curl_version); DEFINE_PRIME1 (lime_curl_version_info);