void pony_asio_event_unsubscribe(asio_event_t* ev) { if((ev == NULL) || (ev->flags == ASIO_DISPOSABLE) || (ev->flags == ASIO_DESTROYED)) return; asio_backend_t* b = ponyint_asio_get_backend(); if(ev->noisy) { ponyint_asio_noisy_remove(); ev->noisy = false; } epoll_ctl(b->epfd, EPOLL_CTL_DEL, ev->fd, NULL); if(ev->flags & ASIO_TIMER) { if(ev->fd != -1) { close(ev->fd); ev->fd = -1; } } if(ev->flags & ASIO_SIGNAL) { int sig = (int)ev->nsec; asio_event_t* prev = ev; if((sig < MAX_SIGNAL) && atomic_compare_exchange_strong_explicit(&b->sighandlers[sig], &prev, NULL, memory_order_release, memory_order_relaxed)) { signal(sig, SIG_DFL); close(ev->fd); ev->fd = -1; } } ev->flags = ASIO_DISPOSABLE; send_request(ev, ASIO_DISPOSABLE); }
PONY_API void pony_asio_event_unsubscribe(asio_event_t* ev) { if((ev == NULL) || (ev->flags == ASIO_DISPOSABLE) || (ev->flags == ASIO_DESTROYED)) { pony_assert(0); return; } asio_backend_t* b = ponyint_asio_get_backend(); pony_assert(b != NULL); if(ev->noisy) { uint64_t old_count = ponyint_asio_noisy_remove(); // tell scheduler threads that asio has no noisy actors // if the old_count was 1 if (old_count == 1) { ponyint_sched_unnoisy_asio(SPECIAL_THREADID_EPOLL); // maybe wake up a scheduler thread if they've all fallen asleep ponyint_sched_maybe_wakeup_if_all_asleep(-1); } ev->noisy = false; } epoll_ctl(b->epfd, EPOLL_CTL_DEL, ev->fd, NULL); if(ev->flags & ASIO_TIMER) { if(ev->fd != -1) { close(ev->fd); ev->fd = -1; } } if(ev->flags & ASIO_SIGNAL) { int sig = (int)ev->nsec; asio_event_t* prev = ev; #ifdef USE_VALGRIND ANNOTATE_HAPPENS_BEFORE(&b->sighandlers[sig]); #endif if((sig < MAX_SIGNAL) && atomic_compare_exchange_strong_explicit(&b->sighandlers[sig], &prev, NULL, memory_order_release, memory_order_relaxed)) { struct sigaction new_action; #if !defined(USE_SCHEDULER_SCALING_PTHREADS) // Make sure we ignore signals related to scheduler sleeping/waking // as the default for those signals is termination if(sig == PONY_SCHED_SLEEP_WAKE_SIGNAL) new_action.sa_handler = empty_signal_handler; else #endif new_action.sa_handler = SIG_DFL; sigemptyset (&new_action.sa_mask); // ask to restart interrupted syscalls to match `signal` behavior new_action.sa_flags = SA_RESTART; sigaction(sig, &new_action, NULL); close(ev->fd); ev->fd = -1; } } ev->flags = ASIO_DISPOSABLE; send_request(ev, ASIO_DISPOSABLE); }