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, 5 months ago) by root
Branch: MAIN
Changes since 1.3: +0 -2 lines
Log Message:
sigh

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_timer tw;
28    
29     GMainContext *gc;
30     };
31    
32     static void
33 root 1.2 timer_cb (EV_P_ ev_timer *w, int revents)
34 root 1.1 {
35     /* nop */
36     }
37    
38     static void
39 root 1.2 io_cb (EV_P_ ev_io *w, int revents)
40 root 1.1 {
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 root 1.3 prepare_cb (EV_P_ ev_prepare *w, int revents)
50 root 1.1 {
51 root 1.3 struct econtext *ctx = (struct econtext *)(((char *)w) - offsetof (struct econtext, pw));
52     gint timeout;
53 root 1.1 int i;
54    
55 root 1.3 if (ctx->nfd >= 0)
56 root 1.1 {
57 root 1.3 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 root 1.1
63 root 1.3 g_main_context_check (ctx->gc, ctx->maxpri, ctx->pfd, ctx->nfd);
64     g_main_context_dispatch (ctx->gc);
65 root 1.1
66 root 1.3 ctx->nfd = -1;
67 root 1.1 }
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 root 1.3 for (i = 0; i < ctx->nfd; ++i)
91 root 1.1 {
92 root 1.3 GPollFD *pfd = ctx->pfd + i;
93     ev_io *iow = ctx->iow + i;
94 root 1.1
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 root 1.3 ctx->nfd = -1;
135 root 1.1 ctx->afd = 0;
136     ctx->iow = 0;
137     ctx->pfd = 0;
138    
139 root 1.3 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 root 1.1 }
144     OUTPUT:
145     RETVAL
146    
147    
148