ARGSUSED*/
| 2163 | |
| 2164 | /*ARGSUSED*/ |
| 2165 | static int |
| 2166 | kqueue_close(struct file *fp, struct thread *td) |
| 2167 | { |
| 2168 | struct kqueue *kq = fp->f_data; |
| 2169 | struct filedesc *fdp; |
| 2170 | int error; |
| 2171 | int filedesc_unlock; |
| 2172 | |
| 2173 | if ((error = kqueue_acquire(fp, &kq))) |
| 2174 | return error; |
| 2175 | kqueue_drain(kq, td); |
| 2176 | |
| 2177 | /* |
| 2178 | * We could be called due to the knote_drop() doing fdrop(), |
| 2179 | * called from kqueue_register(). In this case the global |
| 2180 | * lock is owned, and filedesc sx is locked before, to not |
| 2181 | * take the sleepable lock after non-sleepable. |
| 2182 | */ |
| 2183 | fdp = kq->kq_fdp; |
| 2184 | kq->kq_fdp = NULL; |
| 2185 | if (!sx_xlocked(FILEDESC_LOCK(fdp))) { |
| 2186 | FILEDESC_XLOCK(fdp); |
| 2187 | filedesc_unlock = 1; |
| 2188 | } else |
| 2189 | filedesc_unlock = 0; |
| 2190 | TAILQ_REMOVE(&fdp->fd_kqlist, kq, kq_list); |
| 2191 | if (filedesc_unlock) |
| 2192 | FILEDESC_XUNLOCK(fdp); |
| 2193 | |
| 2194 | kqueue_destroy(kq); |
| 2195 | chgkqcnt(kq->kq_cred->cr_ruidinfo, -1, 0); |
| 2196 | crfree(kq->kq_cred); |
| 2197 | free(kq, M_KQUEUE); |
| 2198 | fp->f_data = NULL; |
| 2199 | |
| 2200 | return (0); |
| 2201 | } |
| 2202 | |
| 2203 | static int |
| 2204 | kqueue_fill_kinfo(struct file *fp, struct kinfo_file *kif, struct filedesc *fdp) |
nothing calls this directly
no test coverage detected