2828#define LCURL_MULTI_NAME LCURL_PREFIX" Multi"
2929static const char * LCURL_MULTI = LCURL_MULTI_NAME ;
3030
31+ #if defined(DEBUG ) || defined(_DEBUG )
32+ static void lcurl__multi_validate_sate (lua_State * L , lcurl_multi_t * p ){
33+ int top = lua_gettop (L );
34+
35+ lua_rawgeti (L , LCURL_LUA_REGISTRY , p -> h_ref );
36+ assert (lua_istable (L , -1 ));
37+
38+ lua_pushnil (L );
39+ while (lua_next (L , -2 )){
40+ lcurl_easy_t * e = lcurl_geteasy_at (L , -1 );
41+ void * ptr = lua_touserdata (L , -2 );
42+
43+ assert (e -> curl == ptr );
44+ assert (e -> multi == p );
45+ assert (e -> L == p -> L );
46+
47+ lua_pop (L , 1 );
48+ }
49+
50+ lua_pop (L , 1 );
51+ assert (lua_gettop (L ) == top );
52+ }
53+ #else
54+ # define lcurl__multi_validate_sate (L , p ) (void*)(0)
55+ #endif
56+
3157void lcurl__multi_assign_lua (lua_State * L , lcurl_multi_t * p , lua_State * value , int assign_easy ){
58+ lcurl__multi_validate_sate (L , p );
59+
3260 if ((assign_easy )&& (p -> L != value )){
3361 lua_rawgeti (L , LCURL_LUA_REGISTRY , p -> h_ref );
3462 lua_pushnil (L );
@@ -145,10 +173,16 @@ static int lcurl_multi_add_handle(lua_State *L){
145173 lua_rawsetp (L , -2 , e -> curl );
146174 lua_settop (L , 1 );
147175
176+ // all `esay` handles have to have same L
177+ lcurl__easy_assign_lua (L , e , p -> L , 0 );
178+
148179 e -> multi = p ;
149180
150181 curL = p -> L ; lcurl__multi_assign_lua (L , p , L , 1 );
151182 code = curl_multi_add_handle (p -> curl , e -> curl );
183+ #ifndef LCURL_RESET_NULL_LUA
184+ if (curL != NULL )
185+ #endif
152186 lcurl__multi_assign_lua (L , p , curL , 1 );
153187
154188 if (code != CURLM_OK ){
@@ -166,30 +200,42 @@ static int lcurl_multi_add_handle(lua_State *L){
166200static int lcurl_multi_remove_handle (lua_State * L ){
167201 lcurl_multi_t * p = lcurl_getmulti (L );
168202 lcurl_easy_t * e = lcurl_geteasy_at (L , 2 );
203+ CURLMcode code = lcurl__multi_remove_handle (L , p , e );
204+
205+ if (code != CURLM_OK ){
206+ return lcurl_fail_ex (L , p -> err_mode , LCURL_ERROR_MULTI , code );
207+ }
208+
209+ lua_settop (L , 1 );
210+ return 1 ;
211+ }
212+
213+ CURLMcode lcurl__multi_remove_handle (lua_State * L , lcurl_multi_t * p , lcurl_easy_t * e ){
169214 CURLMcode code ;
170215 lua_State * curL ;
171216
172217 if (e -> multi != p ){
173218 // cURL returns CURLM_OK for such call so we do the same.
174219 // tested on 7.37.1
175- lua_settop (L , 1 );
176- return 1 ;
220+ return CURLM_OK ;
177221 }
178222
179223 curL = p -> L ; lcurl__multi_assign_lua (L , p , L , 1 );
180224 code = curl_multi_remove_handle (p -> curl , e -> curl );
225+ #ifndef LCURL_RESET_NULL_LUA
226+ if (curL != NULL )
227+ #endif
181228 lcurl__multi_assign_lua (L , p , curL , 1 );
182229
183- if (code != CURLM_OK ){
184- lcurl_fail_ex (L , p -> err_mode , LCURL_ERROR_MULTI , code );
230+ if (code == CURLM_OK ){
231+ e -> multi = NULL ;
232+ lua_rawgeti (L , LCURL_LUA_REGISTRY , p -> h_ref );
233+ lua_pushnil (L );
234+ lua_rawsetp (L , -2 , e -> curl );
235+ lua_pop (L , 1 );
185236 }
186-
187- e -> multi = NULL ;
188- lua_rawgeti (L , LCURL_LUA_REGISTRY , p -> h_ref );
189- lua_pushnil (L );
190- lua_rawsetp (L , -2 , e -> curl );
191- lua_settop (L , 1 );
192- return 1 ;
237+
238+ return code ;
193239}
194240
195241static int lcurl_multi_perform (lua_State * L ){
@@ -200,6 +246,9 @@ static int lcurl_multi_perform(lua_State *L){
200246
201247 curL = p -> L ; lcurl__multi_assign_lua (L , p , L , 1 );
202248 while ((code = curl_multi_perform (p -> curl , & running_handles )) == CURLM_CALL_MULTI_PERFORM );
249+ #ifndef LCURL_RESET_NULL_LUA
250+ if (curL != NULL )
251+ #endif
203252 lcurl__multi_assign_lua (L , p , curL , 1 );
204253
205254 if (code != CURLM_OK ){
@@ -232,6 +281,9 @@ static int lcurl_multi_info_read(lua_State *L){
232281
233282 curL = p -> L ; lcurl__multi_assign_lua (L , p , L , 1 );
234283 code = curl_multi_remove_handle (p -> curl , e -> curl );
284+ #ifndef LCURL_RESET_NULL_LUA
285+ if (curL != NULL )
286+ #endif
235287 lcurl__multi_assign_lua (L , p , curL , 1 );
236288
237289 if (CURLM_OK == code ){
@@ -337,6 +389,9 @@ static int lcurl_multi_socket_action(lua_State *L){
337389
338390 curL = p -> L ; lcurl__multi_assign_lua (L , p , L , 1 );
339391 code = curl_multi_socket_action (p -> curl , s , mask , & n );
392+ #ifndef LCURL_RESET_NULL_LUA
393+ if (curL != NULL )
394+ #endif
340395 lcurl__multi_assign_lua (L , p , curL , 1 );
341396
342397 if (code != CURLM_OK ){
0 commit comments