* Remove all knotes referencing a specified fd must be called with FILEDESC * lock. This prevents a race where a new fd comes along and occupies the * entry and we attach a knote to the fd. */
| 2553 | * entry and we attach a knote to the fd. |
| 2554 | */ |
| 2555 | void |
| 2556 | knote_fdclose(struct thread *td, int fd) |
| 2557 | { |
| 2558 | struct filedesc *fdp = td->td_proc->p_fd; |
| 2559 | struct kqueue *kq; |
| 2560 | struct knote *kn; |
| 2561 | int influx; |
| 2562 | |
| 2563 | FILEDESC_XLOCK_ASSERT(fdp); |
| 2564 | |
| 2565 | /* |
| 2566 | * We shouldn't have to worry about new kevents appearing on fd |
| 2567 | * since filedesc is locked. |
| 2568 | */ |
| 2569 | TAILQ_FOREACH(kq, &fdp->fd_kqlist, kq_list) { |
| 2570 | KQ_LOCK(kq); |
| 2571 | |
| 2572 | again: |
| 2573 | influx = 0; |
| 2574 | while (kq->kq_knlistsize > fd && |
| 2575 | (kn = SLIST_FIRST(&kq->kq_knlist[fd])) != NULL) { |
| 2576 | if (kn_in_flux(kn)) { |
| 2577 | /* someone else might be waiting on our knote */ |
| 2578 | if (influx) |
| 2579 | wakeup(kq); |
| 2580 | kq->kq_state |= KQ_FLUXWAIT; |
| 2581 | msleep(kq, &kq->kq_lock, PSOCK, "kqflxwt", 0); |
| 2582 | goto again; |
| 2583 | } |
| 2584 | kn_enter_flux(kn); |
| 2585 | KQ_UNLOCK(kq); |
| 2586 | influx = 1; |
| 2587 | knote_drop(kn, td); |
| 2588 | KQ_LOCK(kq); |
| 2589 | } |
| 2590 | KQ_UNLOCK_FLUX(kq); |
| 2591 | } |
| 2592 | } |
| 2593 | |
| 2594 | static int |
| 2595 | knote_attach(struct knote *kn, struct kqueue *kq) |
no test coverage detected