|
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() |
@@ -170,7 +174,22 @@ function socket_callback( |
170 | 174 | if action in (CURL_POLL_IN, CURL_POLL_OUT, CURL_POLL_INOUT) |
171 | 175 | readable = action in (CURL_POLL_IN, CURL_POLL_INOUT) |
172 | 176 | writable = action in (CURL_POLL_OUT, CURL_POLL_INOUT) |
173 | | - watcher = FDWatcher(OS_HANDLE(sock), readable, writable) |
| 177 | + watcher = try |
| 178 | + FDWatcher(OS_HANDLE(sock), readable, writable) |
| 179 | + catch watcher_ex |
| 180 | + if watcher_ex isa Base.IOError |
| 181 | + task = @async begin |
| 182 | + lock(multi.lock) do |
| 183 | + @check curl_multi_socket_action(multi.handle, sock, CURL_CSELECT_ERR) |
| 184 | + check_multi_info(multi) |
| 185 | + end |
| 186 | + end |
| 187 | + @isdefined(errormonitor) && errormonitor(task) |
| 188 | + nothing |
| 189 | + else |
| 190 | + rethrow() |
| 191 | + end |
| 192 | + end |
174 | 193 | preserve_handle(watcher) |
175 | 194 | watcher_p = pointer_from_objref(watcher) |
176 | 195 | @check curl_multi_assign(multi.handle, sock, watcher_p) |
|
0 commit comments