… | |
… | |
22 | ev_io *iow; |
22 | ev_io *iow; |
23 | int nfd, afd; |
23 | int nfd, afd; |
24 | gint maxpri; |
24 | gint maxpri; |
25 | |
25 | |
26 | ev_prepare pw; |
26 | ev_prepare pw; |
27 | ev_check cw; |
|
|
28 | ev_timer tw; |
27 | ev_timer tw; |
29 | |
28 | |
30 | GMainContext *gc; |
29 | GMainContext *gc; |
31 | }; |
30 | }; |
32 | |
31 | |
33 | static void |
32 | static void |
34 | timer_cb (ev_timer *w, int revents) |
33 | timer_cb (EV_P_ ev_timer *w, int revents) |
35 | { |
34 | { |
36 | /* nop */ |
35 | /* nop */ |
37 | } |
36 | } |
38 | |
37 | |
39 | static void |
38 | static void |
40 | io_cb (ev_io *w, int revents) |
39 | io_cb (EV_P_ ev_io *w, int revents) |
41 | { |
40 | { |
42 | GPollFD *pfd = (GPollFD *)w->data; |
41 | GPollFD *pfd = (GPollFD *)w->data; |
43 | |
42 | |
44 | pfd->revents |= pfd->events & |
43 | pfd->revents |= pfd->events & |
45 | ((revents & EV_READ ? G_IO_IN : 0) |
44 | ((revents & EV_READ ? G_IO_IN : 0) |
46 | | (revents & EV_READ ? G_IO_OUT : 0)); |
45 | | (revents & EV_READ ? G_IO_OUT : 0)); |
47 | } |
46 | } |
48 | |
47 | |
49 | static void |
48 | 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) |
49 | prepare_cb (EV_P_ ev_prepare *w, int revents) |
71 | { |
50 | { |
72 | struct econtext *ctx = (struct econtext *)(((char *)w) - offsetof (struct econtext, pw)); |
51 | struct econtext *ctx = (struct econtext *)(((char *)w) - offsetof (struct econtext, pw)); |
73 | gint timeout; |
52 | gint timeout; |
74 | int n; |
53 | int i; |
75 | |
54 | |
76 | cleanup (ctx); |
55 | if (ctx->nfd >= 0) |
|
|
56 | { |
|
|
57 | 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 | |
|
|
63 | g_main_context_check (ctx->gc, ctx->maxpri, ctx->pfd, ctx->nfd); |
|
|
64 | g_main_context_dispatch (ctx->gc); |
|
|
65 | |
|
|
66 | ctx->nfd = -1; |
|
|
67 | } |
77 | |
68 | |
78 | g_main_context_prepare (ctx->gc, &ctx->maxpri); |
69 | g_main_context_prepare (ctx->gc, &ctx->maxpri); |
79 | |
70 | |
80 | while (ctx->afd < (ctx->nfd = g_main_context_query ( |
71 | while (ctx->afd < (ctx->nfd = g_main_context_query ( |
81 | ctx->gc, |
72 | ctx->gc, |
… | |
… | |
94 | |
85 | |
95 | ctx->pfd = malloc (ctx->afd * sizeof (GPollFD)); |
86 | ctx->pfd = malloc (ctx->afd * sizeof (GPollFD)); |
96 | ctx->iow = malloc (ctx->afd * sizeof (ev_io)); |
87 | ctx->iow = malloc (ctx->afd * sizeof (ev_io)); |
97 | } |
88 | } |
98 | |
89 | |
99 | for (n = 0; n < ctx->nfd; ++n) |
90 | for (i = 0; i < ctx->nfd; ++i) |
100 | { |
91 | { |
101 | GPollFD *pfd = ctx->pfd + n; |
92 | GPollFD *pfd = ctx->pfd + i; |
102 | ev_io *iow = ctx->iow + n; |
93 | ev_io *iow = ctx->iow + i; |
103 | |
94 | |
104 | pfd->revents = 0; |
95 | pfd->revents = 0; |
105 | |
96 | |
106 | ev_io_init ( |
97 | ev_io_init ( |
107 | iow, |
98 | iow, |
… | |
… | |
110 | (pfd->events & G_IO_IN ? EV_READ : 0) |
101 | (pfd->events & G_IO_IN ? EV_READ : 0) |
111 | | (pfd->events & G_IO_OUT ? EV_WRITE : 0) |
102 | | (pfd->events & G_IO_OUT ? EV_WRITE : 0) |
112 | ); |
103 | ); |
113 | iow->data = (void *)pfd; |
104 | iow->data = (void *)pfd; |
114 | ev_io_start (EV_A_ iow); |
105 | ev_io_start (EV_A_ iow); |
115 | ev_unref (); |
|
|
116 | } |
106 | } |
117 | |
107 | |
118 | if (timeout >= 0) |
108 | if (timeout >= 0) |
119 | { |
109 | { |
120 | ev_timer_set (&ctx->tw, timeout * 1e-3, 0.); |
110 | ev_timer_set (&ctx->tw, timeout * 1e-3, 0.); |
121 | ev_timer_start (EV_A_ &ctx->tw); |
111 | ev_timer_start (EV_A_ &ctx->tw); |
122 | } |
112 | } |
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 | } |
113 | } |
135 | |
114 | |
136 | static struct econtext default_context; |
115 | static struct econtext default_context; |
137 | |
116 | |
138 | MODULE = EV::Glib PACKAGE = EV::Glib |
117 | MODULE = EV::Glib PACKAGE = EV::Glib |
… | |
… | |
150 | { |
129 | { |
151 | GMainContext *gc = get_gcontext (context); |
130 | GMainContext *gc = get_gcontext (context); |
152 | struct econtext *ctx = &default_context; |
131 | struct econtext *ctx = &default_context; |
153 | |
132 | |
154 | ctx->gc = g_main_context_ref (gc); |
133 | ctx->gc = g_main_context_ref (gc); |
155 | ctx->nfd = 0; |
134 | ctx->nfd = -1; |
156 | ctx->afd = 0; |
135 | ctx->afd = 0; |
157 | ctx->iow = 0; |
136 | ctx->iow = 0; |
158 | ctx->pfd = 0; |
137 | ctx->pfd = 0; |
159 | |
138 | |
160 | ev_prepare_init (&ctx->pw, prepare_cb); ev_prepare_start (EV_DEFAULT_ &ctx->pw); |
139 | ev_prepare_init (&ctx->pw, prepare_cb); |
161 | ev_check_init (&ctx->cw, check_cb); ev_check_start (EV_DEFAULT_ &ctx->cw); |
140 | ev_prepare_start (EV_DEFAULT_ &ctx->pw); |
162 | ev_init (&ctx->tw, timer_cb); ev_set_priority (&ctx->tw, EV_MINPRI); |
141 | ev_init (&ctx->tw, timer_cb); |
|
|
142 | ev_set_priority (&ctx->tw, EV_MINPRI); |
163 | } |
143 | } |
164 | OUTPUT: |
144 | OUTPUT: |
165 | RETVAL |
145 | RETVAL |
166 | |
146 | |
167 | |
147 | |