ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Glib-EV/EV.xs
Revision: 1.3
Committed: Thu Dec 20 07:23:50 2007 UTC (16 years, 6 months ago) by root
Branch: MAIN
CVS Tags: rel-2_0
Changes since 1.2: +7 -7 lines
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 root 1.2 timeout_cb (EV_P_ ev_timer *w, int revents)
19 root 1.1 {
20 root 1.3 ev_unloop (EV_A, EVUNLOOP_ONE);
21 root 1.1 }
22    
23     typedef struct
24     {
25     struct ev_io io;
26     int *got_events;
27     GPollFD *pfd;
28     } slot;
29    
30     static void
31 root 1.2 io_cb (EV_P_ ev_io *w, int revents)
32 root 1.1 {
33     slot *s = (slot *)w;
34 root 1.2 int oev = s->pfd->revents;
35 root 1.1
36     s->pfd->revents |= s->pfd->events &
37     ((revents & EV_READ ? G_IO_IN : 0)
38     | (revents & EV_READ ? G_IO_OUT : 0));
39    
40 root 1.2 if (!oev && s->pfd->revents)
41 root 1.1 ++*(s->got_events);
42    
43 root 1.3 ev_unloop (EV_A, EVUNLOOP_ONE);
44 root 1.1 }
45    
46     static gint
47     event_poll_func (GPollFD *fds, guint nfds, gint timeout)
48     {
49     dSP;
50     // yes, I use C99. If your compiler barfs here, fix it, but don't
51     // tell me your compiler vendor was too incompetent to implement
52     // the C standard within the last eight years.
53     ev_timer to;
54     slot slots[nfds];
55     int got_events = 0;
56     int n;
57    
58     for (n = 0; n < nfds; ++n)
59     {
60     GPollFD *pfd = fds + n;
61     slot *s = slots + n;
62    
63     pfd->revents = 0;
64    
65     s->pfd = pfd;
66     s->got_events = &got_events;
67    
68     ev_io_init (
69     &s->io,
70     io_cb,
71     pfd->fd,
72     (pfd->events & G_IO_IN ? EV_READ : 0)
73     | (pfd->events & G_IO_OUT ? EV_WRITE : 0)
74     );
75 root 1.3 ev_io_start (EV_DEFAULT, &s->io);
76 root 1.1 }
77    
78     if (timeout >= 0)
79     {
80     ev_timer_init (&to, timeout_cb, timeout * 1e-3, 0.);
81 root 1.3 ev_timer_start (EV_DEFAULT, &to);
82 root 1.1 }
83    
84 root 1.3 ev_loop (EV_DEFAULT, 0);
85 root 1.1
86     if (timeout >= 0)
87 root 1.3 ev_timer_stop (EV_DEFAULT, &to);
88 root 1.1
89     for (n = 0; n < nfds; ++n)
90 root 1.3 ev_io_stop (EV_DEFAULT, &slots[n].io);
91 root 1.1
92     return got_events;
93     }
94    
95     MODULE = Glib::EV PACKAGE = Glib::EV
96    
97     PROTOTYPES: ENABLE
98    
99     BOOT:
100     {
101     I_EV_API ("Glib::EV");
102     }
103    
104     long
105     install (SV *context)
106     CODE:
107     {
108     GMainContext *ctx = get_gcontext (context);
109    
110     RETVAL = (long)g_main_context_get_poll_func (ctx);
111    
112     g_main_context_set_poll_func (ctx, event_poll_func);
113     }
114     OUTPUT:
115     RETVAL
116    
117     void
118     uninstall (SV *context, long prev_poll_func)
119     CODE:
120     {
121     GMainContext *ctx = get_gcontext (context);
122    
123     g_main_context_set_poll_func (ctx, (GPollFunc) prev_poll_func);
124     }
125    
126