Lines Matching +full:wake +full:- +full:up
18 * Support for the signalfd facility, a Linux-borne facility for
19 * file descriptor-based synchronous signal consumption.
54 * arriving signals should wake only process-local pollers. Additionally,
59 * poll machinery can act upon them without risk of use-after-free. When a
81 * Poller entries in sigfd_proc_state_t`sigfd_list are cleaned up under two
91 * fork-shared signalfd descriptors in conjuction with fork-shared caching poll
93 * wake-ups. This is caused by the pollhead identity of signalfd descriptors
95 * thread-local cache, poll(2) is unaffected by this limitation.
108 * Process exit, cleaning up signalfd pollers:
140 /* Per-instance signalfd device state: */
178 kcondvar_t sp_cv; /* CV for cleaning up */
193 sigfd_proc_state_t *pstate = p->p_sigfd; in signalfd_proc_clean()
195 ASSERT(MUTEX_HELD(&p->p_lock)); in signalfd_proc_clean()
197 VERIFY(list_is_empty(&pstate->sigfd_list)); in signalfd_proc_clean()
199 p->p_sigfd = NULL; in signalfd_proc_clean()
200 list_destroy(&pstate->sigfd_list); in signalfd_proc_clean()
209 mutex_enter(&sp->sp_lock); in signalfd_wake_task()
210 VERIFY(sp->sp_pollev != 0); in signalfd_wake_task()
211 VERIFY(sp->sp_pending); in signalfd_wake_task()
213 const short pollev = sp->sp_pollev; in signalfd_wake_task()
215 sp->sp_pollev = 0; in signalfd_wake_task()
216 mutex_exit(&sp->sp_lock); in signalfd_wake_task()
224 pollwakeup(&sp->sp_pollhead, pollev); in signalfd_wake_task()
226 pollhead_clean(&sp->sp_pollhead); in signalfd_wake_task()
229 mutex_enter(&sp->sp_lock); in signalfd_wake_task()
234 * underlying resource is undergoing clean-up. in signalfd_wake_task()
239 } while (sp->sp_pollev != 0); in signalfd_wake_task()
242 * Indicate that wake task processing is complete. in signalfd_wake_task()
244 * Wake any thread waiting for event delivery to complete if this poller in signalfd_wake_task()
247 sp->sp_pending = false; in signalfd_wake_task()
248 cv_signal(&sp->sp_cv); in signalfd_wake_task()
249 mutex_exit(&sp->sp_lock); in signalfd_wake_task()
255 ASSERT(MUTEX_HELD(&sp->sp_lock)); in signalfd_poller_wake()
257 sp->sp_pollev |= ev; in signalfd_poller_wake()
258 if (!sp->sp_pending) { in signalfd_poller_wake()
259 sp->sp_pending = true; in signalfd_poller_wake()
261 &sp->sp_taskent); in signalfd_poller_wake()
273 sigfd_proc_state_t *pstate = (sigfd_proc_state_t *)p->p_sigfd; in signalfd_pollwake_cb()
275 ASSERT(MUTEX_HELD(&p->p_lock)); in signalfd_pollwake_cb()
278 list_t *pollers = &pstate->sigfd_list; in signalfd_pollwake_cb()
281 mutex_enter(&sp->sp_lock); in signalfd_pollwake_cb()
282 if (sigismember(&sp->sp_mask, sig)) { in signalfd_pollwake_cb()
285 mutex_exit(&sp->sp_lock); in signalfd_pollwake_cb()
298 ASSERT(MUTEX_HELD(&p->p_lock)); in signalfd_proc_pstate()
300 sigfd_proc_state_t *pstate = p->p_sigfd; in signalfd_proc_pstate()
302 mutex_exit(&p->p_lock); in signalfd_proc_pstate()
304 list_create(&pstate->sigfd_list, in signalfd_proc_pstate()
307 pstate->sigfd_pollwake_cb = signalfd_pollwake_cb; in signalfd_proc_pstate()
310 mutex_enter(&p->p_lock); in signalfd_proc_pstate()
311 if (p->p_sigfd == NULL) { in signalfd_proc_pstate()
312 p->p_sigfd = pstate; in signalfd_proc_pstate()
315 list_destroy(&pstate->sigfd_list); in signalfd_proc_pstate()
317 pstate = p->p_sigfd; in signalfd_proc_pstate()
331 ASSERT(MUTEX_HELD(&state->sfd_lock)); in signalfd_poller_associate()
333 mutex_enter(&p->p_lock); in signalfd_poller_associate()
336 pollers = &pstate->sigfd_list; in signalfd_poller_associate()
343 if (sp->sp_state == state) { in signalfd_poller_associate()
344 mutex_exit(&p->p_lock); in signalfd_poller_associate()
354 mutex_exit(&p->p_lock); in signalfd_poller_associate()
357 mutex_init(&sp->sp_lock, NULL, MUTEX_DEFAULT, NULL); in signalfd_poller_associate()
358 cv_init(&sp->sp_cv, NULL, CV_DEFAULT, NULL); in signalfd_poller_associate()
359 sigorset(&sp->sp_mask, &state->sfd_mask); in signalfd_poller_associate()
360 sp->sp_state = state; in signalfd_poller_associate()
361 sp->sp_proc = p; in signalfd_poller_associate()
363 mutex_enter(&p->p_lock); in signalfd_poller_associate()
370 list_insert_tail(&pstate->sigfd_list, sp); in signalfd_poller_associate()
371 list_insert_tail(&state->sfd_pollers, sp); in signalfd_poller_associate()
372 mutex_exit(&p->p_lock); in signalfd_poller_associate()
380 ASSERT(MUTEX_HELD(&state->sfd_lock)); in signalfd_pollers_dissociate()
385 list_t *pollers = &state->sfd_pollers; in signalfd_pollers_dissociate()
387 proc_t *p = sp->sp_proc; in signalfd_pollers_dissociate()
394 * Even if the process in question is racing us to clean-up in in signalfd_pollers_dissociate()
399 mutex_enter(&p->p_lock); in signalfd_pollers_dissociate()
400 if (sp->sp_proc == NULL) { in signalfd_pollers_dissociate()
401 mutex_exit(&p->p_lock); in signalfd_pollers_dissociate()
404 VERIFY3P(sp->sp_proc, ==, p); in signalfd_pollers_dissociate()
405 VERIFY3P(sp->sp_state, ==, state); in signalfd_pollers_dissociate()
406 VERIFY3P(p->p_sigfd, !=, NULL); in signalfd_pollers_dissociate()
408 sigfd_proc_state_t *pstate = p->p_sigfd; in signalfd_pollers_dissociate()
409 list_remove(&pstate->sigfd_list, sp); in signalfd_pollers_dissociate()
410 sp->sp_proc = NULL; in signalfd_pollers_dissociate()
412 /* Wake any lingering pollers referencing the pollhead */ in signalfd_pollers_dissociate()
413 mutex_enter(&sp->sp_lock); in signalfd_pollers_dissociate()
415 mutex_exit(&sp->sp_lock); in signalfd_pollers_dissociate()
417 if (list_is_empty(&pstate->sigfd_list)) { in signalfd_pollers_dissociate()
420 * process, then clean up its state as well. in signalfd_pollers_dissociate()
424 mutex_exit(&p->p_lock); in signalfd_pollers_dissociate()
432 ASSERT(MUTEX_HELD(&state->sfd_lock)); in signalfd_pollers_free()
435 while ((sp = list_remove_head(&state->sfd_pollers)) != NULL) { in signalfd_pollers_free()
436 ASSERT3P(sp->sp_proc, ==, NULL); in signalfd_pollers_free()
438 mutex_enter(&sp->sp_lock); in signalfd_pollers_free()
439 while (sp->sp_pending) { in signalfd_pollers_free()
440 cv_wait(&sp->sp_cv, &sp->sp_lock); in signalfd_pollers_free()
446 ASSERT3P(sp->sp_pollhead.ph_list, ==, NULL); in signalfd_pollers_free()
448 cv_destroy(&sp->sp_cv); in signalfd_pollers_free()
449 mutex_destroy(&sp->sp_lock); in signalfd_pollers_free()
455 * Callback for cleaning up signalfd state from a process during proc_exit().
462 mutex_enter(&p->p_lock); in signalfd_exit_helper()
464 sigfd_proc_state_t *pstate = p->p_sigfd; in signalfd_exit_helper()
466 mutex_exit(&p->p_lock); in signalfd_exit_helper()
471 while ((sp = list_remove_head(&pstate->sigfd_list)) != NULL) { in signalfd_exit_helper()
476 sp->sp_proc = NULL; in signalfd_exit_helper()
478 /* Wake any lingering pollers referencing the pollhead */ in signalfd_exit_helper()
479 mutex_enter(&sp->sp_lock); in signalfd_exit_helper()
481 mutex_exit(&sp->sp_lock); in signalfd_exit_helper()
484 mutex_exit(&p->p_lock); in signalfd_exit_helper()
496 if (minor == -1) { in signalfd_open()
506 mutex_init(&state->sfd_lock, NULL, MUTEX_DEFAULT, NULL); in signalfd_open()
507 list_create(&state->sfd_pollers, sizeof (signalfd_poller_t), in signalfd_open()
509 state->sfd_minor = minor; in signalfd_open()
537 t->t_sigwait = set; in signalfd_consume_signal()
539 mutex_enter(&p->p_lock); in signalfd_consume_signal()
543 const k_sigset_t oldmask = t->t_hold; in signalfd_consume_signal()
544 sigdiffset(&t->t_hold, &t->t_sigwait); in signalfd_consume_signal()
548 ret = cv_waituntil_sig(&t->t_delay_cv, &p->p_lock, in signalfd_consume_signal()
552 mutex_exit(&p->p_lock); in signalfd_consume_signal()
554 ret = -1; in signalfd_consume_signal()
556 mutex_enter(&p->p_lock); in signalfd_consume_signal()
563 t->t_hold = oldmask; in signalfd_consume_signal()
564 t->t_sig_check = 1; in signalfd_consume_signal()
566 if (ret == -1) { in signalfd_consume_signal()
568 mutex_exit(&p->p_lock); in signalfd_consume_signal()
569 sigemptyset(&t->t_sigwait); in signalfd_consume_signal()
574 if (lwp->lwp_cursig == 0 || in signalfd_consume_signal()
575 !sigismember(&t->t_sigwait, lwp->lwp_cursig)) { in signalfd_consume_signal()
581 mutex_exit(&p->p_lock); in signalfd_consume_signal()
582 sigemptyset(&t->t_sigwait); in signalfd_consume_signal()
589 if (lwp->lwp_curinfo != NULL) { in signalfd_consume_signal()
590 k_siginfo_t *infop = &lwp->lwp_curinfo->sq_info; in signalfd_consume_signal()
592 ssi.ssi_signo = infop->si_signo; in signalfd_consume_signal()
593 ssi.ssi_errno = infop->si_errno; in signalfd_consume_signal()
594 ssi.ssi_code = infop->si_code; in signalfd_consume_signal()
595 ssi.ssi_pid = infop->si_pid; in signalfd_consume_signal()
596 ssi.ssi_uid = infop->si_uid; in signalfd_consume_signal()
597 ssi.ssi_fd = infop->si_fd; in signalfd_consume_signal()
598 ssi.ssi_band = infop->si_band; in signalfd_consume_signal()
599 ssi.ssi_trapno = infop->si_trapno; in signalfd_consume_signal()
600 ssi.ssi_status = infop->si_status; in signalfd_consume_signal()
601 ssi.ssi_utime = infop->si_utime; in signalfd_consume_signal()
602 ssi.ssi_stime = infop->si_stime; in signalfd_consume_signal()
603 ssi.ssi_addr = (uint64_t)(intptr_t)infop->si_addr; in signalfd_consume_signal()
609 .si_signo = lwp->lwp_cursig, in signalfd_consume_signal()
619 lwp->lwp_ru.nsignals++; in signalfd_consume_signal()
620 lwp->lwp_cursig = 0; in signalfd_consume_signal()
621 lwp->lwp_extsig = 0; in signalfd_consume_signal()
622 if (lwp->lwp_curinfo != NULL) { in signalfd_consume_signal()
623 siginfofree(lwp->lwp_curinfo); in signalfd_consume_signal()
624 lwp->lwp_curinfo = NULL; in signalfd_consume_signal()
626 mutex_exit(&p->p_lock); in signalfd_consume_signal()
629 sigemptyset(&t->t_sigwait); in signalfd_consume_signal()
652 if (uio->uio_resid < sizeof (signalfd_siginfo_t)) { in signalfd_read()
656 if (uio->uio_fmode & (FNDELAY|FNONBLOCK)) { in signalfd_read()
660 mutex_enter(&state->sfd_lock); in signalfd_read()
661 set = state->sfd_mask; in signalfd_read()
662 mutex_exit(&state->sfd_lock); in signalfd_read()
682 mutex_enter(&state->sfd_lock); in signalfd_read()
683 set = state->sfd_mask; in signalfd_read()
684 mutex_exit(&state->sfd_lock); in signalfd_read()
688 } while (res == 0 && uio->uio_resid >= sizeof (signalfd_siginfo_t)); in signalfd_read()
698 * return (((p->p_sig | t->t_sig) & set) & fillset);
703 return (((p->p_sig.__sigbits[0] | t->t_sig.__sigbits[0]) & in signalfd_sig_pending()
705 ((p->p_sig.__sigbits[1] | t->t_sig.__sigbits[1]) & in signalfd_sig_pending()
707 (((p->p_sig.__sigbits[2] | t->t_sig.__sigbits[2]) & in signalfd_sig_pending()
725 mutex_enter(&state->sfd_lock); in signalfd_poll()
726 if (signalfd_sig_pending(p, t, state->sfd_mask) != 0) { in signalfd_poll()
735 *phpp = &sp->sp_pollhead; in signalfd_poll()
737 mutex_exit(&state->sfd_lock); in signalfd_poll()
749 mutex_enter(&state->sfd_lock); in signalfd_set_mask()
750 state->sfd_mask = kmask; in signalfd_set_mask()
751 list_t *pollers = &state->sfd_pollers; in signalfd_set_mask()
754 mutex_enter(&sp->sp_lock); in signalfd_set_mask()
755 sp->sp_mask = kmask; in signalfd_set_mask()
756 mutex_exit(&sp->sp_lock); in signalfd_set_mask()
758 mutex_exit(&state->sfd_lock); in signalfd_set_mask()
804 mutex_enter(&state->sfd_lock); in signalfd_close()
809 /* ... and free all those (now-dissociated) pollers */ in signalfd_close()
811 ASSERT(list_is_empty(&state->sfd_pollers)); in signalfd_close()
813 mutex_destroy(&state->sfd_lock); in signalfd_close()