1 #if defined(__FreeBSD__) || defined(__APPLE__)
8 static VALUE cKQueueHandler
;
9 static VALUE cEventHandler
;
16 static ID m_deregister
;
20 #define NUM_EVENTS FIX2INT(rb_funcall(rb_cv_get(cEventHandler, "@@actions"), m_size, 0))
23 kqh_event_mask(VALUE klass
, VALUE sym
)
26 if (proc_exit
== id
) {
27 return UINT2NUM(NOTE_EXIT
);
28 } else if (proc_fork
== id
) {
29 return UINT2NUM(NOTE_FORK
);
31 rb_raise(rb_eNotImpError
, "Event `%s` not implemented", rb_id2name(id
));
38 kqh_monitor_process(VALUE klass
, VALUE pid
, VALUE mask
)
40 struct kevent new_event
;
43 u_int fflags
= NUM2UINT(mask
);
45 EV_SET(&new_event
, FIX2UINT(pid
), EVFILT_PROC
,
46 EV_ADD
| EV_ENABLE
, fflags
, 0, 0);
48 if (-1 == kevent(kq
, &new_event
, 1, NULL
, 0, NULL
)) {
49 rb_raise(rb_eStandardError
, strerror(errno
));
58 int nevents
, i
, num_to_fetch
= NUM_EVENTS
;
59 struct kevent
*events
= (struct kevent
*)malloc(num_to_fetch
* sizeof(struct kevent
));
65 rb_raise(rb_eStandardError
, strerror(errno
));
68 nevents
= kevent(kq
, NULL
, 0, events
, num_to_fetch
, &ts
);
71 rb_raise(rb_eStandardError
, strerror(errno
));
73 for (i
= 0; i
< nevents
; i
++) {
74 if (events
[i
].fflags
& NOTE_EXIT
) {
75 rb_funcall(cEventHandler
, m_call
, 2, INT2NUM(events
[i
].ident
), ID2SYM(proc_exit
));
76 rb_funcall(cEventHandler
, m_deregister
, 1, INT2NUM(events
[i
].ident
));
77 } else if (events
[i
].fflags
& NOTE_FORK
) {
78 rb_funcall(cEventHandler
, m_call
, 2, INT2NUM(events
[i
].ident
), ID2SYM(proc_fork
));
85 return INT2FIX(nevents
);
89 Init_kqueue_handler_ext()
94 rb_raise(rb_eStandardError
, "kqueue initilization failed");
97 proc_exit
= rb_intern("proc_exit");
98 proc_fork
= rb_intern("proc_fork");
99 m_call
= rb_intern("call");
100 m_size
= rb_intern("size");
101 m_deregister
= rb_intern("deregister");
103 mGod
= rb_const_get(rb_cObject
, rb_intern("God"));
104 cEventHandler
= rb_const_get(mGod
, rb_intern("EventHandler"));
105 cKQueueHandler
= rb_define_class_under(mGod
, "KQueueHandler", rb_cObject
);
106 rb_define_singleton_method(cKQueueHandler
, "monitor_process", kqh_monitor_process
, 2);
107 rb_define_singleton_method(cKQueueHandler
, "handle_events", kqh_handle_events
, 0);
108 rb_define_singleton_method(cKQueueHandler
, "event_mask", kqh_event_mask
, 1);