Fix. easy:close
removes self from multi
handle.
Change. Do not reset Lua state back to NULL.
This commit is contained in:
parent
367eb1482f
commit
78a4a03e23
5
lakefile
5
lakefile
@ -4,6 +4,7 @@ INITLAKEFILE()
|
|||||||
|
|
||||||
DEFINES = L{DEFINES,
|
DEFINES = L{DEFINES,
|
||||||
IF(WINDOWS, 'DLL_EXPORT', '');
|
IF(WINDOWS, 'DLL_EXPORT', '');
|
||||||
|
IF(DEBUG, 'LCURL_RESET_NULL_LUA', '');
|
||||||
}
|
}
|
||||||
|
|
||||||
cURL = c.shared{'lcurl',
|
cURL = c.shared{'lcurl',
|
||||||
@ -18,7 +19,7 @@ cURL = c.shared{'lcurl',
|
|||||||
target('build', cURL)
|
target('build', cURL)
|
||||||
|
|
||||||
install = target('install', {
|
install = target('install', {
|
||||||
file.group{odir=LIBDIR; src = cURL };
|
file.group{odir=LIBDIR; src = cURL };
|
||||||
file.group{odir=LIBDIR; src = J("src", "lua") ; recurse = true };
|
file.group{odir=LIBDIR; src = J("src", "lua") ; recurse = true };
|
||||||
file.group{odir=J(ROOT, 'examples'); src = 'examples'; recurse = true };
|
file.group{odir=J(ROOT, 'examples'); src = 'examples'; recurse = true };
|
||||||
file.group{odir=TESTDIR; src = 'test'; recurse = true };
|
file.group{odir=TESTDIR; src = 'test'; recurse = true };
|
||||||
@ -30,6 +31,8 @@ target('test', install, function()
|
|||||||
run_test('test_form.lua')
|
run_test('test_form.lua')
|
||||||
run_test('test_pause02.c.lua')
|
run_test('test_pause02.c.lua')
|
||||||
run_test('test_curl.lua')
|
run_test('test_curl.lua')
|
||||||
|
run_test('test_multi_callback.lua')
|
||||||
|
run_test('test_multi_nested_callback.lua')
|
||||||
|
|
||||||
if not test_summary() then
|
if not test_summary() then
|
||||||
quit("test fail")
|
quit("test fail")
|
||||||
|
17
src/lceasy.c
17
src/lceasy.c
@ -40,6 +40,8 @@ static const char *LCURL_EASY = LCURL_EASY_NAME;
|
|||||||
* end)
|
* end)
|
||||||
* ```
|
* ```
|
||||||
* So we have to restore previews Lua state in callback contexts.
|
* So we have to restore previews Lua state in callback contexts.
|
||||||
|
* But if previews Lua state is NULL then we can just do not set it back.
|
||||||
|
* But set it to NULL make esier debug code.
|
||||||
*/
|
*/
|
||||||
void lcurl__easy_assign_lua(lua_State *L, lcurl_easy_t *p, lua_State *value, int assign_multi){
|
void lcurl__easy_assign_lua(lua_State *L, lcurl_easy_t *p, lua_State *value, int assign_multi){
|
||||||
if(p->multi && assign_multi){
|
if(p->multi && assign_multi){
|
||||||
@ -107,6 +109,12 @@ static int lcurl_easy_cleanup(lua_State *L){
|
|||||||
lcurl_easy_t *p = lcurl_geteasy(L);
|
lcurl_easy_t *p = lcurl_geteasy(L);
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
if(p->multi){
|
||||||
|
CURLMcode code = lcurl__multi_remove_handle(L, p->multi, p);
|
||||||
|
|
||||||
|
//! @todo what I can do if I can not remove it???
|
||||||
|
}
|
||||||
|
|
||||||
if(p->curl){
|
if(p->curl){
|
||||||
lua_State *curL;
|
lua_State *curL;
|
||||||
|
|
||||||
@ -114,6 +122,9 @@ static int lcurl_easy_cleanup(lua_State *L){
|
|||||||
// timerfunction called only for single multi handle.
|
// timerfunction called only for single multi handle.
|
||||||
curL = p->L; lcurl__easy_assign_lua(L, p, L, 1);
|
curL = p->L; lcurl__easy_assign_lua(L, p, L, 1);
|
||||||
curl_easy_cleanup(p->curl);
|
curl_easy_cleanup(p->curl);
|
||||||
|
#ifndef LCURL_RESET_NULL_LUA
|
||||||
|
if(curL != NULL)
|
||||||
|
#endif
|
||||||
lcurl__easy_assign_lua(L, p, curL, 1);
|
lcurl__easy_assign_lua(L, p, curL, 1);
|
||||||
|
|
||||||
p->curl = NULL;
|
p->curl = NULL;
|
||||||
@ -163,6 +174,9 @@ static int lcurl_easy_perform(lua_State *L){
|
|||||||
// User should not call `perform` if handle assign to multi
|
// User should not call `perform` if handle assign to multi
|
||||||
curL = p->L; lcurl__easy_assign_lua(L, p, L, 0);
|
curL = p->L; lcurl__easy_assign_lua(L, p, L, 0);
|
||||||
code = curl_easy_perform(p->curl);
|
code = curl_easy_perform(p->curl);
|
||||||
|
#ifndef LCURL_RESET_NULL_LUA
|
||||||
|
if(curL != NULL)
|
||||||
|
#endif
|
||||||
lcurl__easy_assign_lua(L, p, curL, 0);
|
lcurl__easy_assign_lua(L, p, curL, 0);
|
||||||
|
|
||||||
if(p->rbuffer.ref != LUA_NOREF){
|
if(p->rbuffer.ref != LUA_NOREF){
|
||||||
@ -1070,6 +1084,9 @@ static int lcurl_easy_pause(lua_State *L){
|
|||||||
|
|
||||||
curL = p->L; lcurl__easy_assign_lua(L, p, L, 1);
|
curL = p->L; lcurl__easy_assign_lua(L, p, L, 1);
|
||||||
code = curl_easy_pause(p->curl, mask);
|
code = curl_easy_pause(p->curl, mask);
|
||||||
|
#ifndef LCURL_RESET_NULL_LUA
|
||||||
|
if(curL != NULL)
|
||||||
|
#endif
|
||||||
lcurl__easy_assign_lua(L, p, curL, 1);
|
lcurl__easy_assign_lua(L, p, curL, 1);
|
||||||
|
|
||||||
if(code != CURLE_OK){
|
if(code != CURLE_OK){
|
||||||
|
@ -28,7 +28,35 @@
|
|||||||
#define LCURL_MULTI_NAME LCURL_PREFIX" Multi"
|
#define LCURL_MULTI_NAME LCURL_PREFIX" Multi"
|
||||||
static const char *LCURL_MULTI = LCURL_MULTI_NAME;
|
static const char *LCURL_MULTI = LCURL_MULTI_NAME;
|
||||||
|
|
||||||
|
#if defined(DEBUG) || defined(_DEBUG)
|
||||||
|
static void lcurl__multi_validate_sate(lua_State *L, lcurl_multi_t *p){
|
||||||
|
int top = lua_gettop(L);
|
||||||
|
|
||||||
|
lua_rawgeti(L, LCURL_LUA_REGISTRY, p->h_ref);
|
||||||
|
assert(lua_istable(L, -1));
|
||||||
|
|
||||||
|
lua_pushnil(L);
|
||||||
|
while(lua_next(L, -2)){
|
||||||
|
lcurl_easy_t *e = lcurl_geteasy_at(L, -1);
|
||||||
|
void *ptr = lua_touserdata(L, -2);
|
||||||
|
|
||||||
|
assert(e->curl == ptr);
|
||||||
|
assert(e->multi == p);
|
||||||
|
assert(e->L == p->L);
|
||||||
|
|
||||||
|
lua_pop(L, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
lua_pop(L, 1);
|
||||||
|
assert(lua_gettop(L) == top);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
# define lcurl__multi_validate_sate(L, p) (void*)(0)
|
||||||
|
#endif
|
||||||
|
|
||||||
void lcurl__multi_assign_lua(lua_State *L, lcurl_multi_t *p, lua_State *value, int assign_easy){
|
void lcurl__multi_assign_lua(lua_State *L, lcurl_multi_t *p, lua_State *value, int assign_easy){
|
||||||
|
lcurl__multi_validate_sate(L, p);
|
||||||
|
|
||||||
if((assign_easy)&&(p->L != value)){
|
if((assign_easy)&&(p->L != value)){
|
||||||
lua_rawgeti(L, LCURL_LUA_REGISTRY, p->h_ref);
|
lua_rawgeti(L, LCURL_LUA_REGISTRY, p->h_ref);
|
||||||
lua_pushnil(L);
|
lua_pushnil(L);
|
||||||
@ -145,10 +173,16 @@ static int lcurl_multi_add_handle(lua_State *L){
|
|||||||
lua_rawsetp(L, -2, e->curl);
|
lua_rawsetp(L, -2, e->curl);
|
||||||
lua_settop(L, 1);
|
lua_settop(L, 1);
|
||||||
|
|
||||||
|
// all `esay` handles have to have same L
|
||||||
|
lcurl__easy_assign_lua(L, e, p->L, 0);
|
||||||
|
|
||||||
e->multi = p;
|
e->multi = p;
|
||||||
|
|
||||||
curL = p->L; lcurl__multi_assign_lua(L, p, L, 1);
|
curL = p->L; lcurl__multi_assign_lua(L, p, L, 1);
|
||||||
code = curl_multi_add_handle(p->curl, e->curl);
|
code = curl_multi_add_handle(p->curl, e->curl);
|
||||||
|
#ifndef LCURL_RESET_NULL_LUA
|
||||||
|
if(curL != NULL)
|
||||||
|
#endif
|
||||||
lcurl__multi_assign_lua(L, p, curL, 1);
|
lcurl__multi_assign_lua(L, p, curL, 1);
|
||||||
|
|
||||||
if(code != CURLM_OK){
|
if(code != CURLM_OK){
|
||||||
@ -166,30 +200,42 @@ static int lcurl_multi_add_handle(lua_State *L){
|
|||||||
static int lcurl_multi_remove_handle(lua_State *L){
|
static int lcurl_multi_remove_handle(lua_State *L){
|
||||||
lcurl_multi_t *p = lcurl_getmulti(L);
|
lcurl_multi_t *p = lcurl_getmulti(L);
|
||||||
lcurl_easy_t *e = lcurl_geteasy_at(L, 2);
|
lcurl_easy_t *e = lcurl_geteasy_at(L, 2);
|
||||||
|
CURLMcode code = lcurl__multi_remove_handle(L, p, e);
|
||||||
|
|
||||||
|
if(code != CURLM_OK){
|
||||||
|
return lcurl_fail_ex(L, p->err_mode, LCURL_ERROR_MULTI, code);
|
||||||
|
}
|
||||||
|
|
||||||
|
lua_settop(L, 1);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
CURLMcode lcurl__multi_remove_handle(lua_State *L, lcurl_multi_t *p, lcurl_easy_t *e){
|
||||||
CURLMcode code;
|
CURLMcode code;
|
||||||
lua_State *curL;
|
lua_State *curL;
|
||||||
|
|
||||||
if(e->multi != p){
|
if(e->multi != p){
|
||||||
// cURL returns CURLM_OK for such call so we do the same.
|
// cURL returns CURLM_OK for such call so we do the same.
|
||||||
// tested on 7.37.1
|
// tested on 7.37.1
|
||||||
lua_settop(L, 1);
|
return CURLM_OK;
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
curL = p->L; lcurl__multi_assign_lua(L, p, L, 1);
|
curL = p->L; lcurl__multi_assign_lua(L, p, L, 1);
|
||||||
code = curl_multi_remove_handle(p->curl, e->curl);
|
code = curl_multi_remove_handle(p->curl, e->curl);
|
||||||
|
#ifndef LCURL_RESET_NULL_LUA
|
||||||
|
if(curL != NULL)
|
||||||
|
#endif
|
||||||
lcurl__multi_assign_lua(L, p, curL, 1);
|
lcurl__multi_assign_lua(L, p, curL, 1);
|
||||||
|
|
||||||
if(code != CURLM_OK){
|
if(code == CURLM_OK){
|
||||||
lcurl_fail_ex(L, p->err_mode, LCURL_ERROR_MULTI, code);
|
e->multi = NULL;
|
||||||
|
lua_rawgeti(L, LCURL_LUA_REGISTRY, p->h_ref);
|
||||||
|
lua_pushnil(L);
|
||||||
|
lua_rawsetp(L, -2, e->curl);
|
||||||
|
lua_pop(L, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
e->multi = NULL;
|
return code;
|
||||||
lua_rawgeti(L, LCURL_LUA_REGISTRY, p->h_ref);
|
|
||||||
lua_pushnil(L);
|
|
||||||
lua_rawsetp(L, -2, e->curl);
|
|
||||||
lua_settop(L, 1);
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int lcurl_multi_perform(lua_State *L){
|
static int lcurl_multi_perform(lua_State *L){
|
||||||
@ -200,6 +246,9 @@ static int lcurl_multi_perform(lua_State *L){
|
|||||||
|
|
||||||
curL = p->L; lcurl__multi_assign_lua(L, p, L, 1);
|
curL = p->L; lcurl__multi_assign_lua(L, p, L, 1);
|
||||||
while((code = curl_multi_perform(p->curl, &running_handles)) == CURLM_CALL_MULTI_PERFORM);
|
while((code = curl_multi_perform(p->curl, &running_handles)) == CURLM_CALL_MULTI_PERFORM);
|
||||||
|
#ifndef LCURL_RESET_NULL_LUA
|
||||||
|
if(curL != NULL)
|
||||||
|
#endif
|
||||||
lcurl__multi_assign_lua(L, p, curL, 1);
|
lcurl__multi_assign_lua(L, p, curL, 1);
|
||||||
|
|
||||||
if(code != CURLM_OK){
|
if(code != CURLM_OK){
|
||||||
@ -232,6 +281,9 @@ static int lcurl_multi_info_read(lua_State *L){
|
|||||||
|
|
||||||
curL = p->L; lcurl__multi_assign_lua(L, p, L, 1);
|
curL = p->L; lcurl__multi_assign_lua(L, p, L, 1);
|
||||||
code = curl_multi_remove_handle(p->curl, e->curl);
|
code = curl_multi_remove_handle(p->curl, e->curl);
|
||||||
|
#ifndef LCURL_RESET_NULL_LUA
|
||||||
|
if(curL != NULL)
|
||||||
|
#endif
|
||||||
lcurl__multi_assign_lua(L, p, curL, 1);
|
lcurl__multi_assign_lua(L, p, curL, 1);
|
||||||
|
|
||||||
if(CURLM_OK == code){
|
if(CURLM_OK == code){
|
||||||
@ -337,6 +389,9 @@ static int lcurl_multi_socket_action(lua_State *L){
|
|||||||
|
|
||||||
curL = p->L; lcurl__multi_assign_lua(L, p, L, 1);
|
curL = p->L; lcurl__multi_assign_lua(L, p, L, 1);
|
||||||
code = curl_multi_socket_action(p->curl, s, mask, &n);
|
code = curl_multi_socket_action(p->curl, s, mask, &n);
|
||||||
|
#ifndef LCURL_RESET_NULL_LUA
|
||||||
|
if(curL != NULL)
|
||||||
|
#endif
|
||||||
lcurl__multi_assign_lua(L, p, curL, 1);
|
lcurl__multi_assign_lua(L, p, curL, 1);
|
||||||
|
|
||||||
if(code != CURLM_OK){
|
if(code != CURLM_OK){
|
||||||
|
@ -33,4 +33,6 @@ void lcurl_multi_initlib(lua_State *L, int nup);
|
|||||||
|
|
||||||
void lcurl__multi_assign_lua(lua_State *L, lcurl_multi_t *p, lua_State *value, int assign_easy);
|
void lcurl__multi_assign_lua(lua_State *L, lcurl_multi_t *p, lua_State *value, int assign_easy);
|
||||||
|
|
||||||
|
CURLMcode lcurl__multi_remove_handle(lua_State *L, lcurl_multi_t *p, lcurl_easy_t *e);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
x
Reference in New Issue
Block a user