2 #if defined(HAVE_KQUEUE)
8 #if defined(HOST_WIN32)
9 /* We assume that kqueue is not available on windows */
13 #define KQUEUE_NEVENTS 128
15 static gint kqueue_fd;
16 static struct kevent *kqueue_events;
19 kqueue_init (gint wakeup_pipe_fd)
23 kqueue_fd = kqueue ();
24 if (kqueue_fd == -1) {
25 g_warning ("kqueue_init: kqueue () failed, error (%d) %s", errno, g_strerror (errno));
29 EV_SET (&event, wakeup_pipe_fd, EVFILT_READ, EV_ADD | EV_ENABLE, 0, 0, 0);
30 if (kevent (kqueue_fd, &event, 1, NULL, 0, NULL) == -1) {
31 g_warning ("kqueue_init: kevent () failed, error (%d) %s", errno, g_strerror (errno));
36 kqueue_events = g_new0 (struct kevent, KQUEUE_NEVENTS);
44 g_free (kqueue_events);
49 kqueue_update_add (ThreadPoolIOUpdate *update)
53 if ((update->events & MONO_POLLIN) != 0)
54 EV_SET (&event, update->fd, EVFILT_READ, EV_ADD | EV_ENABLE | EV_ONESHOT, 0, 0, 0);
55 if ((update->events & MONO_POLLOUT) != 0)
56 EV_SET (&event, update->fd, EVFILT_WRITE, EV_ADD | EV_ENABLE | EV_ONESHOT, 0, 0, 0);
58 if (kevent (kqueue_fd, &event, 1, NULL, 0, NULL) == -1)
59 g_warning ("kqueue_update_add: kevent(update) failed, error (%d) %s", errno, g_strerror (errno));
63 kqueue_event_wait (void)
67 ready = kevent (kqueue_fd, NULL, 0, kqueue_events, KQUEUE_NEVENTS, NULL);
71 check_for_interruption_critical ();
75 g_warning ("kqueue_event_wait: kevent () failed, error (%d) %s", errno, g_strerror (errno));
84 kqueue_event_fd_at (guint i)
86 return kqueue_events [i].ident;
90 kqueue_event_max (void)
92 return KQUEUE_NEVENTS;
96 kqueue_event_create_sockares_at (guint i, gint fd, MonoMList **list)
98 struct kevent *kqueue_event;
102 kqueue_event = &kqueue_events [i];
103 g_assert (kqueue_event);
105 g_assert (fd == kqueue_event->ident);
107 if (*list && (kqueue_event->filter == EVFILT_READ || (kqueue_event->flags & EV_ERROR) != 0)) {
108 MonoSocketAsyncResult *io_event = get_sockares_for_event (list, MONO_POLLIN);
110 mono_threadpool_ms_enqueue_work_item (((MonoObject*) io_event)->vtable->domain, (MonoObject*) io_event);
112 if (*list && (kqueue_event->filter == EVFILT_WRITE || (kqueue_event->flags & EV_ERROR) != 0)) {
113 MonoSocketAsyncResult *io_event = get_sockares_for_event (list, MONO_POLLOUT);
115 mono_threadpool_ms_enqueue_work_item (((MonoObject*) io_event)->vtable->domain, (MonoObject*) io_event);
119 gint events = get_events (*list);
120 if (kqueue_event->filter == EVFILT_READ && (events & MONO_POLLIN) != 0) {
121 EV_SET (kqueue_event, fd, EVFILT_READ, EV_ADD | EV_ENABLE | EV_ONESHOT, 0, 0, 0);
122 if (kevent (kqueue_fd, kqueue_event, 1, NULL, 0, NULL) == -1)
123 g_warning ("kqueue_event_create_sockares_at: kevent (read) failed, error (%d) %s", errno, g_strerror (errno));
125 if (kqueue_event->filter == EVFILT_WRITE && (events & MONO_POLLOUT) != 0) {
126 EV_SET (kqueue_event, fd, EVFILT_WRITE, EV_ADD | EV_ENABLE | EV_ONESHOT, 0, 0, 0);
127 if (kevent (kqueue_fd, kqueue_event, 1, NULL, 0, NULL) == -1)
128 g_warning ("kqueue_event_create_sockares_at: kevent (write) failed, error (%d) %s", errno, g_strerror (errno));
135 static ThreadPoolIOBackend backend_kqueue = {
137 .cleanup = kqueue_cleanup,
138 .update_add = kqueue_update_add,
139 .event_wait = kqueue_event_wait,
140 .event_max = kqueue_event_max,
141 .event_fd_at = kqueue_event_fd_at,
142 .event_create_sockares_at = kqueue_event_create_sockares_at,