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