|
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