ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/EV-Glib/Glib.xs
Revision: 1.1
Committed: Sat Dec 8 02:49:42 2007 UTC (16 years, 5 months ago) by root
Branch: MAIN
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     timer_cb (ev_timer *w, int revents)
35     {
36     /* nop */
37     }
38    
39     static void
40     io_cb (ev_io *w, int revents)
41     {
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     cleanup (struct econtext *ctx)
51     {
52     int i;
53    
54     for (i = 0; i < ctx->nfd; ++i)
55     {
56     ev_ref ();
57     ev_io_stop (EV_A_ ctx->iow + i);
58     }
59    
60     ctx->nfd = 0;
61    
62     if (ev_is_active (&ctx->tw))
63     {
64     ev_ref ();
65     ev_timer_stop (EV_A_ &ctx->tw);
66     }
67     }
68    
69     static void
70     prepare_cb (ev_prepare *w, int revents)
71     {
72     struct econtext *ctx = (struct econtext *)(((char *)w) - offsetof (struct econtext, pw));
73     gint timeout;
74     int n;
75    
76     cleanup (ctx);
77    
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     ev_unref ();
116     }
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     }
123     }
124    
125     static void
126     check_cb (ev_check *w, int revents)
127     {
128     struct econtext *ctx = (struct econtext *)(((char *)w) - offsetof (struct econtext, cw));
129    
130     cleanup (ctx);
131    
132     g_main_context_check (ctx->gc, ctx->maxpri, ctx->pfd, ctx->nfd);
133     g_main_context_dispatch (ctx->gc);
134     }
135    
136     static struct econtext default_context;
137    
138     MODULE = EV::Glib PACKAGE = EV::Glib
139    
140     PROTOTYPES: ENABLE
141    
142     BOOT:
143     {
144     I_EV_API ("EV::Glib");
145     }
146    
147     long
148     install (SV *context)
149     CODE:
150     {
151     GMainContext *gc = get_gcontext (context);
152     struct econtext *ctx = &default_context;
153    
154     ctx->gc = g_main_context_ref (gc);
155     ctx->nfd = 0;
156     ctx->afd = 0;
157     ctx->iow = 0;
158     ctx->pfd = 0;
159    
160     ev_prepare_init (&ctx->pw, prepare_cb); ev_prepare_start (EV_DEFAULT_ &ctx->pw);
161     ev_check_init (&ctx->cw, check_cb); ev_check_start (EV_DEFAULT_ &ctx->cw);
162     ev_init (&ctx->tw, timer_cb); ev_set_priority (&ctx->tw, EV_MINPRI);
163     }
164     OUTPUT:
165     RETVAL
166    
167    
168