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_FD (gint fd, gint events, gint flags)
22 EV_SET (&event, fd, events, flags, 0, 0, 0);
23 return kevent (kqueue_fd, &event, 1, NULL, 0, NULL);
27 kqueue_init (gint wakeup_pipe_fd)
29 kqueue_fd = kqueue ();
30 if (kqueue_fd == -1) {
31 g_error ("kqueue_init: kqueue () failed, error (%d) %s", errno, g_strerror (errno));
35 if (KQUEUE_INIT_FD (wakeup_pipe_fd, EVFILT_READ, EV_ADD | EV_ENABLE) == -1) {
36 g_error ("kqueue_init: kevent () failed, error (%d) %s", errno, g_strerror (errno));
41 kqueue_events = g_new0 (struct kevent, KQUEUE_NEVENTS);
47 kqueue_register_fd (gint fd, gint events, gboolean is_new)
49 if (events & EVENT_IN) {
50 if (KQUEUE_INIT_FD (fd, EVFILT_READ, EV_ADD | EV_ENABLE) == -1)
51 g_error ("kqueue_register_fd: kevent(read,enable) failed, error (%d) %s", errno, g_strerror (errno));
53 if (KQUEUE_INIT_FD (fd, EVFILT_READ, EV_ADD | EV_DISABLE) == -1)
54 g_error ("kqueue_register_fd: kevent(read,disable) failed, error (%d) %s", errno, g_strerror (errno));
56 if (events & EVENT_OUT) {
57 if (KQUEUE_INIT_FD (fd, EVFILT_WRITE, EV_ADD | EV_ENABLE) == -1)
58 g_error ("kqueue_register_fd: kevent(write,enable) failed, error (%d) %s", errno, g_strerror (errno));
60 if (KQUEUE_INIT_FD (fd, EVFILT_WRITE, EV_ADD | EV_DISABLE) == -1)
61 g_error ("kqueue_register_fd: kevent(write,disable) failed, error (%d) %s", errno, g_strerror (errno));
66 kqueue_remove_fd (gint fd)
68 /* FIXME: a race between closing and adding operation in the Socket managed code trigger a ENOENT error */
69 if (KQUEUE_INIT_FD (fd, EVFILT_READ, EV_DELETE) == -1)
70 g_error ("kqueue_register_fd: kevent(read,delete) failed, error (%d) %s", errno, g_strerror (errno));
71 if (KQUEUE_INIT_FD (fd, EVFILT_WRITE, EV_DELETE) == -1)
72 g_error ("kqueue_register_fd: kevent(write,delete) failed, error (%d) %s", errno, g_strerror (errno));
76 kqueue_event_wait (void (*callback) (gint fd, gint events, gpointer user_data), gpointer user_data)
80 memset (kqueue_events, 0, sizeof (struct kevent) * KQUEUE_NEVENTS);
82 mono_gc_set_skip_thread (TRUE);
85 ready = kevent (kqueue_fd, NULL, 0, kqueue_events, KQUEUE_NEVENTS, NULL);
88 mono_gc_set_skip_thread (FALSE);
96 g_error ("kqueue_event_wait: kevent () failed, error (%d) %s", errno, g_strerror (errno));
104 for (i = 0; i < ready; ++i) {
107 fd = kqueue_events [i].ident;
108 if (kqueue_events [i].filter == EVFILT_READ || (kqueue_events [i].flags & EV_ERROR) != 0)
110 if (kqueue_events [i].filter == EVFILT_WRITE || (kqueue_events [i].flags & EV_ERROR) != 0)
113 callback (fd, events, user_data);
119 static ThreadPoolIOBackend backend_kqueue = {
121 .register_fd = kqueue_register_fd,
122 .remove_fd = kqueue_remove_fd,
123 .event_wait = kqueue_event_wait,