ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Glib-EV/EV.xs
Revision: 1.1
Committed: Sat Nov 24 16:10:22 2007 UTC (16 years, 7 months ago) by root
Branch: MAIN
CVS Tags: rel-1_0, rel-0_1
Log Message:
*** empty log message ***

File Contents

# Content
1 #include "EXTERN.h"
2 #include "perl.h"
3 #include "XSUB.h"
4
5 #include <glib.h>
6 #include "EVAPI.h"
7
8 static GMainContext *
9 get_gcontext (SV *context)
10 {
11 if (!SvOK (context))
12 return g_main_context_default ();
13
14 croak ("only the default context is currently supported.");
15 }
16
17 static void
18 timeout_cb (ev_timer *w, int revents)
19 {
20 ev_unloop (EVUNLOOP_ONE);
21 }
22
23 typedef struct
24 {
25 struct ev_io io;
26 int *got_events;
27 GPollFD *pfd;
28 } slot;
29
30 static void
31 io_cb (ev_io *w, int revents)
32 {
33 slot *s = (slot *)w;
34
35 s->pfd->revents |= s->pfd->events &
36 ((revents & EV_READ ? G_IO_IN : 0)
37 | (revents & EV_READ ? G_IO_OUT : 0));
38
39 if (s->pfd->revents)
40 ++*(s->got_events);
41
42 ev_unloop (EVUNLOOP_ONE);
43 }
44
45 static gint
46 event_poll_func (GPollFD *fds, guint nfds, gint timeout)
47 {
48 dSP;
49 // yes, I use C99. If your compiler barfs here, fix it, but don't
50 // tell me your compiler vendor was too incompetent to implement
51 // the C standard within the last eight years.
52 ev_timer to;
53 slot slots[nfds];
54 int got_events = 0;
55 int n;
56
57 for (n = 0; n < nfds; ++n)
58 {
59 GPollFD *pfd = fds + n;
60 slot *s = slots + n;
61
62 pfd->revents = 0;
63
64 s->pfd = pfd;
65 s->got_events = &got_events;
66
67 ev_io_init (
68 &s->io,
69 io_cb,
70 pfd->fd,
71 (pfd->events & G_IO_IN ? EV_READ : 0)
72 | (pfd->events & G_IO_OUT ? EV_WRITE : 0)
73 );
74 ev_io_start (&s->io);
75 }
76
77 if (timeout >= 0)
78 {
79 ev_timer_init (&to, timeout_cb, timeout * 1e-3, 0.);
80 ev_timer_start (&to);
81 }
82
83 ev_loop (0);
84
85 if (timeout >= 0)
86 ev_timer_stop (&to);
87
88 for (n = 0; n < nfds; ++n)
89 ev_io_stop (&slots[n].io);
90
91 return got_events;
92 }
93
94 MODULE = Glib::EV PACKAGE = Glib::EV
95
96 PROTOTYPES: ENABLE
97
98 BOOT:
99 {
100 I_EV_API ("Glib::EV");
101 }
102
103 long
104 install (SV *context)
105 CODE:
106 {
107 GMainContext *ctx = get_gcontext (context);
108
109 RETVAL = (long)g_main_context_get_poll_func (ctx);
110
111 g_main_context_set_poll_func (ctx, event_poll_func);
112 }
113 OUTPUT:
114 RETVAL
115
116 void
117 uninstall (SV *context, long prev_poll_func)
118 CODE:
119 {
120 GMainContext *ctx = get_gcontext (context);
121
122 g_main_context_set_poll_func (ctx, (GPollFunc) prev_poll_func);
123 }
124
125