ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/EV-Glib/Glib.xs
Revision: 1.3
Committed: Sat Dec 8 03:17:40 2007 UTC (16 years, 5 months ago) by root
Branch: MAIN
Changes since 1.2: +22 -41 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 printf ("ctx rev %d %x:%x\n", w->fd, pfd->events, pfd->revents);//D
48 }
49
50 static void
51 prepare_cb (EV_P_ ev_prepare *w, int revents)
52 {
53 struct econtext *ctx = (struct econtext *)(((char *)w) - offsetof (struct econtext, pw));
54 gint timeout;
55 int i;
56
57 if (ctx->nfd >= 0)
58 {
59 for (i = 0; i < ctx->nfd; ++i)
60 ev_io_stop (EV_A_ ctx->iow + i);
61
62 if (ev_is_active (&ctx->tw))
63 ev_timer_stop (EV_A_ &ctx->tw);
64
65 g_main_context_check (ctx->gc, ctx->maxpri, ctx->pfd, ctx->nfd);
66 g_main_context_dispatch (ctx->gc);
67
68 ctx->nfd = -1;
69 }
70
71 g_main_context_prepare (ctx->gc, &ctx->maxpri);
72
73 while (ctx->afd < (ctx->nfd = g_main_context_query (
74 ctx->gc,
75 ctx->maxpri,
76 &timeout,
77 ctx->pfd,
78 ctx->afd))
79 )
80 {
81 free (ctx->pfd);
82 free (ctx->iow);
83
84 ctx->afd = 1;
85 while (ctx->afd < ctx->nfd)
86 ctx->afd <<= 1;
87
88 ctx->pfd = malloc (ctx->afd * sizeof (GPollFD));
89 ctx->iow = malloc (ctx->afd * sizeof (ev_io));
90 }
91
92 for (i = 0; i < ctx->nfd; ++i)
93 {
94 GPollFD *pfd = ctx->pfd + i;
95 ev_io *iow = ctx->iow + i;
96
97 pfd->revents = 0;
98
99 ev_io_init (
100 iow,
101 io_cb,
102 pfd->fd,
103 (pfd->events & G_IO_IN ? EV_READ : 0)
104 | (pfd->events & G_IO_OUT ? EV_WRITE : 0)
105 );
106 iow->data = (void *)pfd;
107 ev_io_start (EV_A_ iow);
108 }
109
110 if (timeout >= 0)
111 {
112 ev_timer_set (&ctx->tw, timeout * 1e-3, 0.);
113 ev_timer_start (EV_A_ &ctx->tw);
114 }
115 }
116
117 static struct econtext default_context;
118
119 MODULE = EV::Glib PACKAGE = EV::Glib
120
121 PROTOTYPES: ENABLE
122
123 BOOT:
124 {
125 I_EV_API ("EV::Glib");
126 }
127
128 long
129 install (SV *context)
130 CODE:
131 {
132 GMainContext *gc = get_gcontext (context);
133 struct econtext *ctx = &default_context;
134
135 ctx->gc = g_main_context_ref (gc);
136 ctx->nfd = -1;
137 ctx->afd = 0;
138 ctx->iow = 0;
139 ctx->pfd = 0;
140
141 ev_prepare_init (&ctx->pw, prepare_cb);
142 ev_prepare_start (EV_DEFAULT_ &ctx->pw);
143 ev_init (&ctx->tw, timer_cb);
144 ev_set_priority (&ctx->tw, EV_MINPRI);
145 }
146 OUTPUT:
147 RETVAL
148
149
150