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

# 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 root 1.3
47     printf ("ctx rev %d %x:%x\n", w->fd, pfd->events, pfd->revents);//D
48 root 1.1 }
49    
50     static void
51 root 1.3 prepare_cb (EV_P_ ev_prepare *w, int revents)
52 root 1.1 {
53 root 1.3 struct econtext *ctx = (struct econtext *)(((char *)w) - offsetof (struct econtext, pw));
54     gint timeout;
55 root 1.1 int i;
56    
57 root 1.3 if (ctx->nfd >= 0)
58 root 1.1 {
59 root 1.3 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 root 1.1
65 root 1.3 g_main_context_check (ctx->gc, ctx->maxpri, ctx->pfd, ctx->nfd);
66     g_main_context_dispatch (ctx->gc);
67 root 1.1
68 root 1.3 ctx->nfd = -1;
69 root 1.1 }
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 root 1.3 for (i = 0; i < ctx->nfd; ++i)
93 root 1.1 {
94 root 1.3 GPollFD *pfd = ctx->pfd + i;
95     ev_io *iow = ctx->iow + i;
96 root 1.1
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 root 1.3 ctx->nfd = -1;
137 root 1.1 ctx->afd = 0;
138     ctx->iow = 0;
139     ctx->pfd = 0;
140    
141 root 1.3 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 root 1.1 }
146     OUTPUT:
147     RETVAL
148    
149    
150