@@ -217,6 +217,17 @@ function TimersList(msecs, unrefed) { |
217 | 217 | this.nextTick = false; |
218 | 218 | } |
219 | 219 |
|
| 220 | +function deleteTimersList(list, msecs) { |
| 221 | + // Either refedLists[msecs] or unrefedLists[msecs] may have been removed and |
| 222 | + // recreated since the reference to `list` was created. Make sure they're |
| 223 | + // the same instance of the list before destroying. |
| 224 | + if (list._unrefed === true && list === unrefedLists[msecs]) { |
| 225 | + delete unrefedLists[msecs]; |
| 226 | + } else if (list === refedLists[msecs]) { |
| 227 | + delete refedLists[msecs]; |
| 228 | + } |
| 229 | +} |
| 230 | + |
220 | 231 | function listOnTimeout() { |
221 | 232 | var list = this._list; |
222 | 233 | var msecs = list.msecs; |
@@ -288,14 +299,7 @@ function listOnTimeout() { |
288 | 299 | debug('%d list empty', msecs); |
289 | 300 | assert(L.isEmpty(list)); |
290 | 301 |
|
291 | | - // Either refedLists[msecs] or unrefedLists[msecs] may have been removed and |
292 | | - // recreated since the reference to `list` was created. Make sure they're |
293 | | - // the same instance of the list before destroying. |
294 | | - if (list._unrefed === true && list === unrefedLists[msecs]) { |
295 | | - delete unrefedLists[msecs]; |
296 | | - } else if (list === refedLists[msecs]) { |
297 | | - delete refedLists[msecs]; |
298 | | - } |
| 302 | + deleteTimersList(list, msecs); |
299 | 303 |
|
300 | 304 | // Do not close the underlying handle if its ownership has changed |
301 | 305 | // (e.g it was unrefed in its callback). |
@@ -329,24 +333,34 @@ function tryOnTimeout(timer, list) { |
329 | 333 | } |
330 | 334 | } |
331 | 335 |
|
332 | | - if (!threw) return; |
| 336 | + if (threw) { |
| 337 | + const { msecs } = list; |
| 338 | + |
| 339 | + if (L.isEmpty(list)) { |
| 340 | + deleteTimersList(list, msecs); |
333 | 341 |
|
334 | | - // Postpone all later list events to next tick. We need to do this |
335 | | - // so that the events are called in the order they were created. |
336 | | - const lists = list._unrefed === true ? unrefedLists : refedLists; |
337 | | - for (var key in lists) { |
338 | | - if (key > list.msecs) { |
339 | | - lists[key].nextTick = true; |
| 342 | + if (!list._timer.owner) |
| 343 | + list._timer.close(); |
| 344 | + } else { |
| 345 | + // Postpone all later list events to next tick. We need to do this |
| 346 | + // so that the events are called in the order they were created. |
| 347 | + const lists = list._unrefed === true ? unrefedLists : refedLists; |
| 348 | + for (var key in lists) { |
| 349 | + if (key > msecs) { |
| 350 | + lists[key].nextTick = true; |
| 351 | + } |
| 352 | + } |
| 353 | + |
| 354 | + // We need to continue processing after domain error handling |
| 355 | + // is complete, but not by using whatever domain was left over |
| 356 | + // when the timeout threw its exception. |
| 357 | + const domain = process.domain; |
| 358 | + process.domain = null; |
| 359 | + // If we threw, we need to process the rest of the list in nextTick. |
| 360 | + process.nextTick(listOnTimeoutNT, list); |
| 361 | + process.domain = domain; |
340 | 362 | } |
341 | 363 | } |
342 | | - // We need to continue processing after domain error handling |
343 | | - // is complete, but not by using whatever domain was left over |
344 | | - // when the timeout threw its exception. |
345 | | - const domain = process.domain; |
346 | | - process.domain = null; |
347 | | - // If we threw, we need to process the rest of the list in nextTick. |
348 | | - process.nextTick(listOnTimeoutNT, list); |
349 | | - process.domain = domain; |
350 | 364 | } |
351 | 365 | } |
352 | 366 |
|
|