ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/EV-Glib/Glib.xs
Revision: 1.8
Committed: Sat Jan 31 09:48:22 2009 UTC (15 years, 2 months ago) by root
Branch: MAIN
CVS Tags: rel-2_01, HEAD
Changes since 1.7: +1 -1 lines
Log Message:
*** empty log message ***

File Contents

# Content
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 ev_check cw;
28 ev_timer tw;
29
30 GMainContext *gc;
31 };
32
33 static void
34 timer_cb (EV_P_ ev_timer *w, int revents)
35 {
36 /* nop */
37 }
38
39 static void
40 io_cb (EV_P_ ev_io *w, int revents)
41 {
42 /* nop */
43 }
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
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 for (i = 0; i < ctx->nfd; ++i)
76 {
77 GPollFD *pfd = ctx->pfd + i;
78 ev_io *iow = ctx->iow + i;
79
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 ev_set_priority (iow, EV_MINPRI);
91 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 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 (EV_A, iow);
115
116 pfd->revents |= pfd->events &
117 ((revents & EV_READ ? G_IO_IN : 0)
118 | (revents & EV_WRITE ? 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 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 ctx->nfd = 0;
150 ctx->afd = 0;
151 ctx->iow = 0;
152 ctx->pfd = 0;
153
154 ev_prepare_init (&ctx->pw, prepare_cb);
155 ev_set_priority (&ctx->pw, EV_MINPRI);
156 ev_prepare_start (EV_DEFAULT, &ctx->pw);
157
158 ev_check_init (&ctx->cw, check_cb);
159 ev_set_priority (&ctx->cw, EV_MAXPRI);
160 ev_check_start (EV_DEFAULT, &ctx->cw);
161
162 ev_init (&ctx->tw, timer_cb);
163 ev_set_priority (&ctx->tw, EV_MINPRI);
164 }
165 OUTPUT:
166 RETVAL
167
168
169