Redesign cURL to avoid GC activity

This commit is contained in:
Joshua Granick
2018-06-20 23:29:31 -07:00
parent 831c619c0b
commit 23caa4d36a
6 changed files with 845 additions and 286 deletions

View File

@@ -858,18 +858,16 @@ class NativeCFFI {
#end
#if (lime_cffi && !macro && lime_curl)
#if !hl
@:cffi private static function lime_curl_getdate (date:String, now:Float):Float;
@:cffi private static function lime_curl_global_cleanup ():Void;
#if !hl
@:cffi private static function lime_curl_global_init (flags:Int):Int;
#else
private static function lime_curl_global_init (flags:Int):Int { return 0; }
#end
@:cffi private static function lime_curl_version ():Dynamic;
@:cffi private static function lime_curl_version_info (type:Int):Dynamic;
@:cffi private static function lime_curl_easy_cleanup (handle:CFFIPointer):Void;
@:cffi private static function lime_curl_easy_duphandle (handle:CFFIPointer):CFFIPointer;
@:cffi private static function lime_curl_easy_escape (curl:CFFIPointer, url:String, length:Int):Dynamic;
@:cffi private static function lime_curl_easy_flush (curl:CFFIPointer):Void;
@:cffi private static function lime_curl_easy_getinfo (curl:CFFIPointer, info:Int):Dynamic;
@:cffi private static function lime_curl_easy_init ():CFFIPointer;
@:cffi private static function lime_curl_easy_pause (handle:CFFIPointer, bitmask:Int):Int;
@@ -887,6 +885,34 @@ class NativeCFFI {
@: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;
#else
@:hlNative("lime", "lime_curl_getdate") private static function lime_curl_getdate (date:String, now:Float):Float { return 0; }
@:hlNative("lime", "lime_curl_global_cleanup") private static function lime_curl_global_cleanup ():Void {}
@:hlNative("lime", "lime_curl_global_init") private static function lime_curl_global_init (flags:Int):Int { return 0; }
@:hlNative("lime", "lime_curl_version") private static function lime_curl_version ():hl.Bytes { return null; }
@:hlNative("lime", "lime_curl_version_info") private static function lime_curl_version_info (type:Int):Dynamic { return null; }
@:hlNative("lime", "lime_curl_easy_cleanup") private static function lime_curl_easy_cleanup (handle:CFFIPointer):Void {}
@:hlNative("lime", "lime_curl_easy_duphandle") private static function lime_curl_easy_duphandle (handle:CFFIPointer):CFFIPointer { return null; }
@:hlNative("lime", "lime_curl_easy_escape") private static function lime_curl_easy_escape (curl:CFFIPointer, url:String, length:Int):hl.Bytes { return null; }
@:hlNative("lime", "lime_curl_easy_flush") private static function lime_curl_easy_flush (curl:CFFIPointer):Void {}
@:hlNative("lime", "lime_curl_easy_getinfo") private static function lime_curl_easy_getinfo (curl:CFFIPointer, info:Int):Dynamic { return null; }
@:hlNative("lime", "lime_curl_easy_init") private static function lime_curl_easy_init ():CFFIPointer { return null; }
@:hlNative("lime", "lime_curl_easy_pause") private static function lime_curl_easy_pause (handle:CFFIPointer, bitmask:Int):Int { return 0; }
@:hlNative("lime", "lime_curl_easy_perform") private static function lime_curl_easy_perform (easy_handle:CFFIPointer):Int { return 0; }
@:hlNative("lime", "lime_curl_easy_recv") private static function lime_curl_easy_recv (curl:CFFIPointer, buffer:Float, buflen:Int, n:Int):Int { return 0; };
@:hlNative("lime", "lime_curl_easy_reset") private static function lime_curl_easy_reset (curl:CFFIPointer):Void {}
@:hlNative("lime", "lime_curl_easy_send") private static function lime_curl_easy_send (curl:CFFIPointer, buffer:Float, buflen:Int, n:Int):Int { return 0; }
@:hlNative("lime", "lime_curl_easy_setopt") private static function lime_curl_easy_setopt (handle:CFFIPointer, option:Int, parameter:Dynamic, writeBytes:Bytes):Int { return 0; }
@:hlNative("lime", "lime_curl_easy_strerror") private static function lime_curl_easy_strerror (errornum:Int):hl.Bytes { return null; }
@:hlNative("lime", "lime_curl_easy_unescape") private static function lime_curl_easy_unescape (curl:CFFIPointer, url:String, inlength:Int, outlength:Int):hl.Bytes { return null; }
@:hlNative("lime", "lime_curl_multi_init") private static function lime_curl_multi_init ():CFFIPointer { return null; }
@:hlNative("lime", "lime_curl_multi_add_handle") private static function lime_curl_multi_add_handle (multi_handle:CFFIPointer, curl_handle:CFFIPointer):Int { return 0; }
@:hlNative("lime", "lime_curl_multi_get_running_handles") private static function lime_curl_multi_get_running_handles (multi_handle:CFFIPointer):Int { return 0; }
@:hlNative("lime", "lime_curl_multi_info_read") private static function lime_curl_multi_info_read (multi_handle:CFFIPointer, object:Dynamic):Dynamic { return null; }
@:hlNative("lime", "lime_curl_multi_perform") private static function lime_curl_multi_perform (multi_handle:CFFIPointer):Int { return 0; }
@:hlNative("lime", "lime_curl_multi_remove_handle") private static function lime_curl_multi_remove_handle (multi_handle:CFFIPointer, curl_handle:CFFIPointer):Int { return 0; }
@:hlNative("lime", "lime_curl_multi_wait") private static function lime_curl_multi_wait (multi_handle:CFFIPointer, timeout_ms:Int):Int { return 0; }
#end
#end
#if (lime_cffi && !macro && lime_opengl)

View File

@@ -68,7 +68,11 @@ class CURL {
public function escape (url:String, length:Int):String {
#if (lime_cffi && lime_curl && !macro)
return NativeCFFI.lime_curl_easy_escape (handle, url, length);
var result = NativeCFFI.lime_curl_easy_escape (handle, url, length);
#if hl
var result = @:privateAccess String.fromUTF8 (result);
#end
return result;
#else
return null;
#end
@@ -174,21 +178,80 @@ class CURL {
public function setOption (option:CURLOption, parameter:Dynamic):CURLCode {
#if (lime_cffi && lime_curl && !macro)
if (option == CURLOption.WRITEFUNCTION) {
var bytes = null;
switch (option) {
if (writeBytes == null) writeBytes = Bytes.alloc (1024);
return cast NativeCFFI.lime_curl_easy_setopt (handle, cast (option, Int), parameter, writeBytes);
case CURLOption.PROGRESSFUNCTION:
var callback:CURL->Float->Float->Float->Float->Void = cast parameter;
parameter = function (dltotal:Float, dlnow:Float, ultotal:Float, ulnow:Float) {
callback (this, dltotal, dlnow, ultotal, ulnow);
}
} else if (option == CURLOption.HEADERFUNCTION) {
case CURLOption.XFERINFOFUNCTION:
var callback:CURL->Int->Int->Int->Int->Int = cast parameter;
parameter = function (dltotal:Int, dlnow:Int, ultotal:Int, ulnow:Int) {
return callback (this, dltotal, dlnow, ultotal, ulnow);
}
if (headerBytes == null) headerBytes = Bytes.alloc (1024);
return cast NativeCFFI.lime_curl_easy_setopt (handle, cast (option, Int), parameter, headerBytes);
case CURLOption.WRITEFUNCTION:
var callback:CURL->Bytes->Int = cast parameter;
parameter = function (bytes:Bytes) {
return callback (this, bytes);
}
bytes = Bytes.alloc (0);
} else {
// case CURLOption.READFUNCTION:
// Impossible to support with GC blocking restrictions
// TODO: Unsafe version?
// return cast 0;
return cast NativeCFFI.lime_curl_easy_setopt (handle, cast (option, Int), parameter, null);
case CURLOption.READDATA:
bytes = parameter;
case CURLOption.HEADERFUNCTION:
var callback:CURL->String->Void = cast parameter;
#if hl
parameter = function (header:hl.Bytes) {
callback (this, @:privateAccess String.fromUTF8 (header));
}
#else
parameter = function (header:String) {
callback (this, header);
}
#end
case CURLOption.HTTPHEADER:
#if hl
var headers:Array<String> = cast parameter;
var _headers = new hl.NativeArray<String> (headers.length);
for (i in 0...headers.length) _headers[i] = headers[i];
parameter = _headers;
#end
default:
}
return cast NativeCFFI.lime_curl_easy_setopt (handle, cast (option, Int), parameter, bytes);
#else
return cast 0;
#end
@@ -199,7 +262,11 @@ class CURL {
public static function strerror (code:CURLCode):String {
#if (lime_cffi && lime_curl && !macro)
return NativeCFFI.lime_curl_easy_strerror (cast (code, Int));
var result = NativeCFFI.lime_curl_easy_strerror (cast (code, Int));
#if hl
var result = @:privateAccess String.fromUTF8 (result);
#end
return result;
#else
return null;
#end
@@ -210,7 +277,11 @@ class CURL {
public function unescape (url:String, inLength:Int, outLength:Int):String {
#if (lime_cffi && lime_curl && !macro)
return NativeCFFI.lime_curl_easy_unescape (handle, url, inLength, outLength);
var result = NativeCFFI.lime_curl_easy_unescape (handle, url, inLength, outLength);
#if hl
var result = @:privateAccess String.fromUTF8 (result);
#end
return result;
#else
return null;
#end
@@ -221,7 +292,11 @@ class CURL {
public static function version ():String {
#if (lime_cffi && lime_curl && !macro)
return NativeCFFI.lime_curl_version ();
var result = NativeCFFI.lime_curl_version ();
#if hl
var result = @:privateAccess String.fromUTF8 (result);
#end
return result;
#else
return null;
#end

View File

@@ -53,7 +53,10 @@ class CURLMulti {
public function infoRead ():CURLMsg {
#if (lime_cffi && lime_curl && !macro)
var msg:Dynamic = NativeCFFI.lime_curl_multi_info_read (handle);
#if hl
var object:{ easy_handle:CFFIPointer, result:Int } = { easy_handle: null, result: 0 };
#end
var msg:Dynamic = NativeCFFI.lime_curl_multi_info_read (handle #if hl , object #end);
var result = null;
if (msg != null) {

View File

@@ -11,8 +11,8 @@ package lime.net.curl;
var USERPWD = 10005;
var PROXYUSERPWD = 10006;
var RANGE = 10007;
//var INFILE = 10009;
//var READDATA = 10009;
var INFILE = 10009;
var READDATA = 10009;
var ERRORBUFFER = 10010;
var WRITEFUNCTION = 20011;
var READFUNCTION = 20012;

File diff suppressed because it is too large Load Diff

View File

@@ -92,11 +92,120 @@ namespace lime {
}
void* ValuePointer::Call (void* arg0) { return 0; }
void* ValuePointer::Call (void* arg0, void* arg1) { return 0; }
void* ValuePointer::Call (void* arg0, void* arg1, void* arg2) { return 0; }
void* ValuePointer::Call (void* arg0, void* arg1, void* arg2, void* arg3) { return 0; }
void* ValuePointer::Call (void* arg0, void* arg1, void* arg2, void* arg3, void* arg4) { return 0; }
void* ValuePointer::Call (void* arg0) {
if (!hlValue) {
return val_call1 ((value)Get (), (value)arg0);
} else {
return hl_dyn_call ((vclosure*)hlValue, &((vdynamic*)arg0), 1);
}
}
void* ValuePointer::Call (void* arg0, void* arg1) {
if (!hlValue) {
return val_call2 ((value)Get (), (value)arg0, (value)arg1);
} else {
vdynamic* args[] = {
(vdynamic*)arg0,
(vdynamic*)arg1,
};
return hl_dyn_call ((vclosure*)hlValue, (vdynamic**)&args, 2);
}
}
void* ValuePointer::Call (void* arg0, void* arg1, void* arg2) {
if (!hlValue) {
return val_call3 ((value)Get (), (value)arg0, (value)arg1, (value)arg2);
} else {
vdynamic* args[] = {
(vdynamic*)arg0,
(vdynamic*)arg1,
(vdynamic*)arg2,
};
return hl_dyn_call ((vclosure*)hlValue, (vdynamic**)&args, 3);
}
}
void* ValuePointer::Call (void* arg0, void* arg1, void* arg2, void* arg3) {
if (!hlValue) {
value vals[] = {
(value)arg0,
(value)arg1,
(value)arg2,
(value)arg3,
};
return val_callN ((value)Get (), vals, 4);
} else {
vdynamic* args[] = {
(vdynamic*)arg0,
(vdynamic*)arg1,
(vdynamic*)arg2,
(vdynamic*)arg3,
};
return hl_dyn_call ((vclosure*)hlValue, (vdynamic**)&args, 4);
}
}
void* ValuePointer::Call (void* arg0, void* arg1, void* arg2, void* arg3, void* arg4) {
if (!hlValue) {
value vals[] = {
(value)arg0,
(value)arg1,
(value)arg2,
(value)arg3,
(value)arg4,
};
return val_callN ((value)Get (), vals, 5);
} else {
vdynamic* args[] = {
(vdynamic*)arg0,
(vdynamic*)arg1,
(vdynamic*)arg2,
(vdynamic*)arg3,
(vdynamic*)arg4,
};
return hl_dyn_call ((vclosure*)hlValue, (vdynamic**)&args, 5);
}
}
void* ValuePointer::Get () const {