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