ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/EV-Glib/Glib.xs
Revision: 1.4
Committed: Sat Dec 8 03:17:46 2007 UTC (16 years, 10 months ago) by root
Branch: MAIN
Changes since 1.3: +0 -2 lines
Log Message:
sigh

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_timer tw;
28
29 GMainContext *gc;
30 };
31
32 static void
33 timer_cb (EV_P_ ev_timer *w, int revents)
34 {
35 /* nop */
36 }
37
38 static void
39 io_cb (EV_P_ ev_io *w, int revents)
40 {
41 GPollFD *pfd = (GPollFD *)w->data;
42
43 pfd->revents |= pfd->events &
44 ((revents & EV_READ ? G_IO_IN : 0)
45 | (revents & EV_READ ? G_IO_OUT : 0));
46 }
47
48 static void
49 prepare_cb (EV_P_ ev_prepare *w, int revents)
50 {
51 struct econtext *ctx = (struct econtext *)(((char *)w) - offsetof (struct econtext, pw));
52 gint timeout;
53 int i;
54
55 if (ctx->nfd >= 0)
56 {
57 for (i = 0; i < ctx->nfd; ++i)
58 ev_io_stop (EV_A_ ctx->iow + i);
59
60 if (ev_is_active (&ctx->tw))
61 ev_timer_stop (EV_A_ &ctx->tw);
62
63 g_main_context_check (ctx->gc, ctx->maxpri, ctx->pfd, ctx->nfd);
64 g_main_context_dispatch (ctx->gc);
65
66 ctx->nfd = -1;
67 }
68
69 g_main_context_prepare (ctx->gc, &ctx->maxpri);
70
71 while (ctx->afd < (ctx->nfd = g_main_context_query (
72 ctx->gc,
73 ctx->maxpri,
74 &timeout,
75 ctx->pfd,
76 ctx->afd))
77 )
78 {
79 free (ctx->pfd);
80 free (ctx->iow);
81
82 ctx->afd = 1;
83 while (ctx->afd < ctx->nfd)
84 ctx->afd <<= 1;
85
86 ctx->pfd = malloc (ctx->afd * sizeof (GPollFD));
87 ctx->iow = malloc (ctx->afd * sizeof (ev_io));
88 }
89
90 for (i = 0; i < ctx->nfd; ++i)
91 {
92 GPollFD *pfd = ctx->pfd + i;
93 ev_io *iow = ctx->iow + i;
94
95 pfd->revents = 0;
96
97 ev_io_init (
98 iow,
99 io_cb,
100 pfd->fd,
101 (pfd->events & G_IO_IN ? EV_READ : 0)
102 | (pfd->events & G_IO_OUT ? EV_WRITE : 0)
103 );
104 iow->data = (void *)pfd;
105 ev_io_start (EV_A_ iow);
106 }
107
108 if (timeout >= 0)
109 {
110 ev_timer_set (&ctx->tw, timeout * 1e-3, 0.);
111 ev_timer_start (EV_A_ &ctx->tw);
112 }
113 }
114
115 static struct econtext default_context;
116
117 MODULE = EV::Glib PACKAGE = EV::Glib
118
119 PROTOTYPES: ENABLE
120
121 BOOT:
122 {
123 I_EV_API ("EV::Glib");
124 }
125
126 long
127 install (SV *context)
128 CODE:
129 {
130 GMainContext *gc = get_gcontext (context);
131 struct econtext *ctx = &default_context;
132
133 ctx->gc = g_main_context_ref (gc);
134 ctx->nfd = -1;
135 ctx->afd = 0;
136 ctx->iow = 0;
137 ctx->pfd = 0;
138
139 ev_prepare_init (&ctx->pw, prepare_cb);
140 ev_prepare_start (EV_DEFAULT_ &ctx->pw);
141 ev_init (&ctx->tw, timer_cb);
142 ev_set_priority (&ctx->tw, EV_MINPRI);
143 }
144 OUTPUT:
145 RETVAL
146
147
148