ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/EV-Glib/Glib.xs
Revision: 1.6
Committed: Sat Dec 8 04:16:09 2007 UTC (16 years, 10 months ago) by root
Branch: MAIN
CVS Tags: rel-0_1
Changes since 1.5: +34 -31 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 <stddef.h>
6    
7     #include <glib.h>
8     #include "EVAPI.h"
9    
10     static GMainContext *
11     get_gcontext (SV *context)
12     {
13     if (!SvOK (context))
14     return g_main_context_default ();
15    
16     croak ("only the default context is currently supported.");
17     }
18    
19     struct econtext
20     {
21     GPollFD *pfd;
22     ev_io *iow;
23     int nfd, afd;
24     gint maxpri;
25    
26     ev_prepare pw;
27 root 1.5 ev_check cw;
28 root 1.1 ev_timer tw;
29    
30     GMainContext *gc;
31     };
32    
33     static void
34 root 1.2 timer_cb (EV_P_ ev_timer *w, int revents)
35 root 1.1 {
36     /* nop */
37     }
38    
39     static void
40 root 1.2 io_cb (EV_P_ ev_io *w, int revents)
41 root 1.1 {
42 root 1.6 /* nop */
43 root 1.5 }
44    
45     static void
46     prepare_cb (EV_P_ ev_prepare *w, int revents)
47     {
48     struct econtext *ctx = (struct econtext *)(((char *)w) - offsetof (struct econtext, pw));
49     gint timeout;
50     int i;
51    
52     g_main_context_dispatch (ctx->gc);
53 root 1.1
54     g_main_context_prepare (ctx->gc, &ctx->maxpri);
55    
56     while (ctx->afd < (ctx->nfd = g_main_context_query (
57     ctx->gc,
58     ctx->maxpri,
59     &timeout,
60     ctx->pfd,
61     ctx->afd))
62     )
63     {
64     free (ctx->pfd);
65     free (ctx->iow);
66    
67     ctx->afd = 1;
68     while (ctx->afd < ctx->nfd)
69     ctx->afd <<= 1;
70    
71     ctx->pfd = malloc (ctx->afd * sizeof (GPollFD));
72     ctx->iow = malloc (ctx->afd * sizeof (ev_io));
73     }
74    
75 root 1.3 for (i = 0; i < ctx->nfd; ++i)
76 root 1.1 {
77 root 1.3 GPollFD *pfd = ctx->pfd + i;
78     ev_io *iow = ctx->iow + i;
79 root 1.1
80     pfd->revents = 0;
81    
82     ev_io_init (
83     iow,
84     io_cb,
85     pfd->fd,
86     (pfd->events & G_IO_IN ? EV_READ : 0)
87     | (pfd->events & G_IO_OUT ? EV_WRITE : 0)
88     );
89     iow->data = (void *)pfd;
90 root 1.6 ev_set_priority (iow, EV_MINPRI);
91 root 1.1 ev_io_start (EV_A_ iow);
92     }
93    
94     if (timeout >= 0)
95     {
96     ev_timer_set (&ctx->tw, timeout * 1e-3, 0.);
97     ev_timer_start (EV_A_ &ctx->tw);
98     }
99     }
100    
101 root 1.6 static void
102     check_cb (EV_P_ ev_check *w, int revents)
103     {
104     struct econtext *ctx = (struct econtext *)(((char *)w) - offsetof (struct econtext, cw));
105     int i;
106    
107     for (i = 0; i < ctx->nfd; ++i)
108     {
109     ev_io *iow = ctx->iow + i;
110    
111     if (ev_is_pending (iow))
112     {
113     GPollFD *pfd = ctx->pfd + i;
114     int revents = ev_clear_pending (iow);
115    
116     pfd->revents |= pfd->events &
117     ((revents & EV_READ ? G_IO_IN : 0)
118     | (revents & EV_READ ? G_IO_OUT : 0));
119     }
120    
121     ev_io_stop (EV_A_ iow);
122     }
123    
124     if (ev_is_active (&ctx->tw))
125     ev_timer_stop (EV_A_ &ctx->tw);
126    
127     g_main_context_check (ctx->gc, ctx->maxpri, ctx->pfd, ctx->nfd);
128     }
129    
130 root 1.1 static struct econtext default_context;
131    
132     MODULE = EV::Glib PACKAGE = EV::Glib
133    
134     PROTOTYPES: ENABLE
135    
136     BOOT:
137     {
138     I_EV_API ("EV::Glib");
139     }
140    
141     long
142     install (SV *context)
143     CODE:
144     {
145     GMainContext *gc = get_gcontext (context);
146     struct econtext *ctx = &default_context;
147    
148     ctx->gc = g_main_context_ref (gc);
149 root 1.6 ctx->nfd = 0;
150 root 1.1 ctx->afd = 0;
151     ctx->iow = 0;
152     ctx->pfd = 0;
153    
154 root 1.3 ev_prepare_init (&ctx->pw, prepare_cb);
155 root 1.6 ev_set_priority (&ctx->pw, EV_MINPRI);
156 root 1.3 ev_prepare_start (EV_DEFAULT_ &ctx->pw);
157 root 1.5
158     ev_check_init (&ctx->cw, check_cb);
159 root 1.6 ev_set_priority (&ctx->cw, EV_MAXPRI);
160 root 1.5 ev_check_start (EV_DEFAULT_ &ctx->cw);
161    
162 root 1.3 ev_init (&ctx->tw, timer_cb);
163     ev_set_priority (&ctx->tw, EV_MINPRI);
164 root 1.1 }
165     OUTPUT:
166     RETVAL
167    
168    
169