static void mm_do_atexit(void) { mm_hook_call(&mm_exit_hook, true); mm_log_relay(); mm_log_flush(); }
static void mm_event_kqueue_poll(struct mm_event_kqueue *event_backend, mm_timeout_t timeout) { ENTER(); DEBUG("poll: changes: %d, timeout: %lu", event_backend->nevents, (unsigned long) timeout); // Calculate the event wait timeout. struct timespec ts; ts.tv_sec = timeout / 1000000; ts.tv_nsec = (timeout % 1000000) * 1000; // Publish the log before a possible sleep. mm_log_relay(); // Poll the system for events. int n = kevent(event_backend->event_fd, event_backend->events, event_backend->nevents, event_backend->events, MM_EVENT_KQUEUE_NEVENTS, &ts); DEBUG("kevent changed: %d, received: %d", event_backend->nevents, n); if (n < 0) { if (errno == EINTR) mm_warning(errno, "kevent"); else mm_error(errno, "kevent"); event_backend->nevents = 0; } else { event_backend->nevents = n; } LEAVE(); }
mm_event_listener_timedwait(struct mm_event_listener *listener, mm_ring_seqno_t stamp, mm_timeout_t timeout) { ENTER(); #if ENABLE_LINUX_FUTEX struct timespec ts; ts.tv_sec = (timeout / 1000000); ts.tv_nsec = (timeout % 1000000) * 1000; // Publish the log before a sleep. mm_log_relay(); int rc = mm_syscall_4(SYS_futex, mm_event_listener_futex(listener), FUTEX_WAIT_PRIVATE, stamp, (uintptr_t) &ts); if (rc != 0 && errno != EWOULDBLOCK && errno != ETIMEDOUT) mm_fatal(errno, "futex"); #elif ENABLE_MACH_SEMAPHORE (void) stamp; mach_timespec_t ts; ts.tv_sec = (timeout / 1000000); ts.tv_nsec = (timeout % 1000000) * 1000; // Publish the log before a sleep. mm_log_relay(); kern_return_t r = semaphore_timedwait(listener->semaphore, ts); if (r != KERN_SUCCESS && unlikely(r != KERN_OPERATION_TIMED_OUT)) mm_fatal(0, "semaphore_timedwait"); #else mm_timeval_t time = mm_clock_gettime_realtime() + timeout; mm_thread_monitor_lock(&listener->monitor); #if ENABLE_NOTIFY_STAMP if (stamp == mm_event_listener_enqueue_stamp(listener)) mm_thread_monitor_timedwait(&listener->monitor, time); #else if (listener->notify_stamp == stamp) mm_thread_monitor_timedwait(&listener->monitor, time); #endif mm_thread_monitor_unlock(&listener->monitor); #endif LEAVE(); }