|
43 | 43 |
|
44 | 44 | function add_handle(multi::Multi, easy::Easy)
|
45 | 45 | connect_semaphore_acquire(easy)
|
46 |
| - lock(multi.lock) do |
| 46 | + added = lock(multi.lock) do |
47 | 47 | if isempty(multi.easies)
|
48 | 48 | preserve_handle(multi)
|
49 | 49 | end
|
50 | 50 | push!(multi.easies, easy)
|
51 | 51 | init!(multi)
|
52 | 52 | @check curl_multi_add_handle(multi.handle, easy.handle)
|
53 | 53 | end
|
| 54 | + if added != 0 |
| 55 | + connect_semaphore_release(easy) |
| 56 | + end |
| 57 | + return added |
54 | 58 | end
|
55 | 59 |
|
56 | 60 | const MULTIS_LOCK = Base.ReentrantLock()
|
@@ -179,7 +183,22 @@ function socket_callback(
|
179 | 183 | if action in (CURL_POLL_IN, CURL_POLL_OUT, CURL_POLL_INOUT)
|
180 | 184 | readable = action in (CURL_POLL_IN, CURL_POLL_INOUT)
|
181 | 185 | writable = action in (CURL_POLL_OUT, CURL_POLL_INOUT)
|
182 |
| - watcher = FDWatcher(OS_HANDLE(sock), readable, writable) |
| 186 | + watcher = try |
| 187 | + FDWatcher(OS_HANDLE(sock), readable, writable) |
| 188 | + catch watcher_ex |
| 189 | + if watcher_ex isa Base.IOError |
| 190 | + task = @async begin |
| 191 | + lock(multi.lock) do |
| 192 | + @check curl_multi_socket_action(multi.handle, sock, CURL_CSELECT_ERR) |
| 193 | + check_multi_info(multi) |
| 194 | + end |
| 195 | + end |
| 196 | + @isdefined(errormonitor) && errormonitor(task) |
| 197 | + nothing |
| 198 | + else |
| 199 | + rethrow() |
| 200 | + end |
| 201 | + end |
183 | 202 | preserve_handle(watcher)
|
184 | 203 | watcher_p = pointer_from_objref(watcher)
|
185 | 204 | @check curl_multi_assign(multi.handle, sock, watcher_p)
|
|
0 commit comments