@@ -58,10 +58,12 @@ local function make_iterator(self, perform)
5858
5959 end
6060
61- local remain = # self ._easy
62- for _ , e in ipairs (self ._easy ) do
63- e :setopt_writefunction (function (str ) buffers :append (e , " data" , str ) end )
64- e :setopt_headerfunction (function (str ) buffers :append (e , " header" , str ) end )
61+ local remain = self ._easy .n
62+ for h , e in pairs (self ._easy ) do
63+ if h ~= ' n' then
64+ e :setopt_writefunction (function (str ) buffers :append (e , " data" , str ) end )
65+ e :setopt_headerfunction (function (str ) buffers :append (e , " header" , str ) end )
66+ end
6567 end
6668
6769 assert (perform (self ))
@@ -78,19 +80,16 @@ local function make_iterator(self, perform)
7880
7981 if n <= remain then
8082 while true do
81- local e , ok , err = assert (self :info_read ())
82- if e == 0 then break end
83- for _ , a in ipairs (self ._easy ) do
84- if e == a :handle () then e = a break end
85- end
83+ local h , ok , err = assert (self :info_read ())
84+ if h == 0 then break end
85+ local e = assert (self ._easy [h ])
8686 if ok then
8787 ok = e :getinfo_response_code () or ok
8888 buffers :append (e , " done" , ok )
8989 else buffers :append (e , " error" , err ) end
9090 end
9191 remain = n
9292 end
93-
9493 end
9594 end
9695end
@@ -276,7 +275,7 @@ local add_handle = wrap_function("add_handle")
276275local remove_handle = wrap_function (" remove_handle" )
277276
278277function Multi :__init ()
279- self ._easy = {}
278+ self ._easy = {n = 0 }
280279 return self
281280end
282281
@@ -285,14 +284,26 @@ function Multi:perform()
285284end
286285
287286function Multi :add_handle (e )
288- self ._easy = self ._easy or {}
289- self ._easy [# self ._easy + 1 ] = e
290- return add_handle (self , e :handle ())
287+ assert (self ._easy .n >= 0 )
288+
289+ local h = e :handle ()
290+ if self ._easy [h ] then return self end
291+
292+ local ok , err = add_handle (self , h )
293+ if not ok then return nil , err end
294+ self ._easy [h ], self ._easy .n = e , self ._easy .n + 1
295+ return self
291296end
292297
293298function Multi :remove_handle (e )
294- self ._easy [# self ._easy + 1 ] = e
295- return remove_handle (self , e :handle ())
299+ local h = e :handle ()
300+
301+ if self ._easy [h ] then
302+ self ._easy [h ], self ._easy .n = nil , self ._easy .n - 1
303+ end
304+ assert (self ._easy .n >= 0 )
305+
306+ return remove_handle (self , h )
296307end
297308
298309end
@@ -348,26 +359,39 @@ end
348359local Multi = class (curl .multi ) do
349360
350361function Multi :__init ()
351- self ._easy = {}
362+ self ._easy = {n = 0 }
352363 return self
353364end
354365
355366function Multi :iperform ()
356367 return make_iterator (self , self .perform )
357368end
358369
359- local add_handle = wrap_function (" add_handle" )
360370function Multi :add_handle (e )
361- self ._easy [# self ._easy + 1 ] = e
362- return add_handle (self , e :handle ())
371+ assert (self ._easy .n >= 0 )
372+
373+ local h = e :handle ()
374+ if self ._easy [h ] then return self end
375+
376+ local ok , err = add_handle (self , h )
377+ if not ok then return nil , err end
378+ self ._easy [h ], self ._easy .n = e , self ._easy .n + 1
379+ return self
363380end
364381
365- local remove_handle = wrap_function (" remove_handle" )
366382function Multi :remove_handle (e )
367- self ._easy [# self ._easy + 1 ] = e
368- return remove_handle (self , e :handle ())
383+ local h = e :handle ()
384+
385+ if self ._easy [h ] then
386+ self ._easy [h ], self ._easy .n = nil , self ._easy .n - 1
387+ end
388+ assert (self ._easy .n >= 0 )
389+
390+ return remove_handle (self , h )
369391end
370392
393+ -- ! @fixme Multi:info_read(true) should also remove easy handle from self._easy
394+
371395end
372396---- ---------------------------------------
373397
0 commit comments