* Even if we are locked, we may need to drop the lock to allow any influx * knotes time to "settle". */
| 2492 | * knotes time to "settle". |
| 2493 | */ |
| 2494 | void |
| 2495 | knlist_cleardel(struct knlist *knl, struct thread *td, int islocked, int killkn) |
| 2496 | { |
| 2497 | struct knote *kn, *kn2; |
| 2498 | struct kqueue *kq; |
| 2499 | |
| 2500 | KASSERT(!knl->kl_autodestroy, ("cleardel for autodestroy %p", knl)); |
| 2501 | if (islocked) |
| 2502 | KNL_ASSERT_LOCKED(knl); |
| 2503 | else { |
| 2504 | KNL_ASSERT_UNLOCKED(knl); |
| 2505 | again: /* need to reacquire lock since we have dropped it */ |
| 2506 | knl->kl_lock(knl->kl_lockarg); |
| 2507 | } |
| 2508 | |
| 2509 | SLIST_FOREACH_SAFE(kn, &knl->kl_list, kn_selnext, kn2) { |
| 2510 | kq = kn->kn_kq; |
| 2511 | KQ_LOCK(kq); |
| 2512 | if (kn_in_flux(kn)) { |
| 2513 | KQ_UNLOCK(kq); |
| 2514 | continue; |
| 2515 | } |
| 2516 | knlist_remove_kq(knl, kn, 1, 1); |
| 2517 | if (killkn) { |
| 2518 | kn_enter_flux(kn); |
| 2519 | KQ_UNLOCK(kq); |
| 2520 | knote_drop_detached(kn, td); |
| 2521 | } else { |
| 2522 | /* Make sure cleared knotes disappear soon */ |
| 2523 | kn->kn_flags |= EV_EOF | EV_ONESHOT; |
| 2524 | KQ_UNLOCK(kq); |
| 2525 | } |
| 2526 | kq = NULL; |
| 2527 | } |
| 2528 | |
| 2529 | if (!SLIST_EMPTY(&knl->kl_list)) { |
| 2530 | /* there are still in flux knotes remaining */ |
| 2531 | kn = SLIST_FIRST(&knl->kl_list); |
| 2532 | kq = kn->kn_kq; |
| 2533 | KQ_LOCK(kq); |
| 2534 | KASSERT(kn_in_flux(kn), ("knote removed w/o list lock")); |
| 2535 | knl->kl_unlock(knl->kl_lockarg); |
| 2536 | kq->kq_state |= KQ_FLUXWAIT; |
| 2537 | msleep(kq, &kq->kq_lock, PSOCK | PDROP, "kqkclr", 0); |
| 2538 | kq = NULL; |
| 2539 | goto again; |
| 2540 | } |
| 2541 | |
| 2542 | if (islocked) |
| 2543 | KNL_ASSERT_LOCKED(knl); |
| 2544 | else { |
| 2545 | knl->kl_unlock(knl->kl_lockarg); |
| 2546 | KNL_ASSERT_UNLOCKED(knl); |
| 2547 | } |
| 2548 | } |
| 2549 | |
| 2550 | /* |
| 2551 | * Remove all knotes referencing a specified fd must be called with FILEDESC |
nothing calls this directly
no test coverage detected