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

# User Rev Content
1 root 1.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