… | |
… | |
37 | } |
37 | } |
38 | |
38 | |
39 | static void |
39 | static void |
40 | io_cb (EV_P_ ev_io *w, int revents) |
40 | io_cb (EV_P_ ev_io *w, int revents) |
41 | { |
41 | { |
42 | GPollFD *pfd = (GPollFD *)w->data; |
42 | /* nop */ |
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 | check_cb (EV_P_ ev_check *w, int revents) |
|
|
51 | { |
|
|
52 | struct econtext *ctx = (struct econtext *)(((char *)w) - offsetof (struct econtext, cw)); |
|
|
53 | |
|
|
54 | if (ctx->nfd >= 0) |
|
|
55 | { |
|
|
56 | int i; |
|
|
57 | |
|
|
58 | for (i = 0; i < ctx->nfd; ++i) |
|
|
59 | ev_io_stop (EV_A_ ctx->iow + i); |
|
|
60 | |
|
|
61 | if (ev_is_active (&ctx->tw)) |
|
|
62 | ev_timer_stop (EV_A_ &ctx->tw); |
|
|
63 | |
|
|
64 | g_main_context_check (ctx->gc, ctx->maxpri, ctx->pfd, ctx->nfd); |
|
|
65 | |
|
|
66 | ctx->nfd = -1; |
|
|
67 | } |
|
|
68 | } |
43 | } |
69 | |
44 | |
70 | static void |
45 | static void |
71 | prepare_cb (EV_P_ ev_prepare *w, int revents) |
46 | prepare_cb (EV_P_ ev_prepare *w, int revents) |
72 | { |
47 | { |
73 | struct econtext *ctx = (struct econtext *)(((char *)w) - offsetof (struct econtext, pw)); |
48 | struct econtext *ctx = (struct econtext *)(((char *)w) - offsetof (struct econtext, pw)); |
74 | gint timeout; |
49 | gint timeout; |
75 | int i; |
50 | int i; |
76 | |
|
|
77 | check_cb (EV_A_ &ctx->cw, 0); |
|
|
78 | |
51 | |
79 | g_main_context_dispatch (ctx->gc); |
52 | g_main_context_dispatch (ctx->gc); |
80 | |
53 | |
81 | g_main_context_prepare (ctx->gc, &ctx->maxpri); |
54 | g_main_context_prepare (ctx->gc, &ctx->maxpri); |
82 | |
55 | |
… | |
… | |
112 | pfd->fd, |
85 | pfd->fd, |
113 | (pfd->events & G_IO_IN ? EV_READ : 0) |
86 | (pfd->events & G_IO_IN ? EV_READ : 0) |
114 | | (pfd->events & G_IO_OUT ? EV_WRITE : 0) |
87 | | (pfd->events & G_IO_OUT ? EV_WRITE : 0) |
115 | ); |
88 | ); |
116 | iow->data = (void *)pfd; |
89 | iow->data = (void *)pfd; |
117 | ev_set_priority (&ctx->cw, ev_priority (w) + 1); |
90 | ev_set_priority (iow, EV_MINPRI); |
118 | ev_io_start (EV_A_ iow); |
91 | ev_io_start (EV_A_ iow); |
119 | } |
92 | } |
120 | |
93 | |
121 | if (timeout >= 0) |
94 | if (timeout >= 0) |
122 | { |
95 | { |
123 | ev_timer_set (&ctx->tw, timeout * 1e-3, 0.); |
96 | ev_timer_set (&ctx->tw, timeout * 1e-3, 0.); |
124 | ev_timer_start (EV_A_ &ctx->tw); |
97 | ev_timer_start (EV_A_ &ctx->tw); |
125 | } |
98 | } |
|
|
99 | } |
|
|
100 | |
|
|
101 | static void |
|
|
102 | check_cb (EV_P_ ev_check *w, int revents) |
|
|
103 | { |
|
|
104 | struct econtext *ctx = (struct econtext *)(((char *)w) - offsetof (struct econtext, cw)); |
|
|
105 | int i; |
|
|
106 | |
|
|
107 | for (i = 0; i < ctx->nfd; ++i) |
|
|
108 | { |
|
|
109 | ev_io *iow = ctx->iow + i; |
|
|
110 | |
|
|
111 | if (ev_is_pending (iow)) |
|
|
112 | { |
|
|
113 | GPollFD *pfd = ctx->pfd + i; |
|
|
114 | int revents = ev_clear_pending (iow); |
|
|
115 | |
|
|
116 | pfd->revents |= pfd->events & |
|
|
117 | ((revents & EV_READ ? G_IO_IN : 0) |
|
|
118 | | (revents & EV_READ ? G_IO_OUT : 0)); |
|
|
119 | } |
|
|
120 | |
|
|
121 | ev_io_stop (EV_A_ iow); |
|
|
122 | } |
|
|
123 | |
|
|
124 | if (ev_is_active (&ctx->tw)) |
|
|
125 | ev_timer_stop (EV_A_ &ctx->tw); |
|
|
126 | |
|
|
127 | g_main_context_check (ctx->gc, ctx->maxpri, ctx->pfd, ctx->nfd); |
126 | } |
128 | } |
127 | |
129 | |
128 | static struct econtext default_context; |
130 | static struct econtext default_context; |
129 | |
131 | |
130 | MODULE = EV::Glib PACKAGE = EV::Glib |
132 | MODULE = EV::Glib PACKAGE = EV::Glib |
… | |
… | |
142 | { |
144 | { |
143 | GMainContext *gc = get_gcontext (context); |
145 | GMainContext *gc = get_gcontext (context); |
144 | struct econtext *ctx = &default_context; |
146 | struct econtext *ctx = &default_context; |
145 | |
147 | |
146 | ctx->gc = g_main_context_ref (gc); |
148 | ctx->gc = g_main_context_ref (gc); |
147 | ctx->nfd = -1; |
149 | ctx->nfd = 0; |
148 | ctx->afd = 0; |
150 | ctx->afd = 0; |
149 | ctx->iow = 0; |
151 | ctx->iow = 0; |
150 | ctx->pfd = 0; |
152 | ctx->pfd = 0; |
151 | |
153 | |
152 | ev_prepare_init (&ctx->pw, prepare_cb); |
154 | ev_prepare_init (&ctx->pw, prepare_cb); |
|
|
155 | ev_set_priority (&ctx->pw, EV_MINPRI); |
153 | ev_prepare_start (EV_DEFAULT_ &ctx->pw); |
156 | ev_prepare_start (EV_DEFAULT_ &ctx->pw); |
154 | |
157 | |
155 | ev_check_init (&ctx->cw, check_cb); |
158 | ev_check_init (&ctx->cw, check_cb); |
156 | ev_set_priority (&ctx->cw, EV_MAXPRI - 1); |
159 | ev_set_priority (&ctx->cw, EV_MAXPRI); |
157 | ev_check_start (EV_DEFAULT_ &ctx->cw); |
160 | ev_check_start (EV_DEFAULT_ &ctx->cw); |
158 | |
161 | |
159 | ev_init (&ctx->tw, timer_cb); |
162 | ev_init (&ctx->tw, timer_cb); |
160 | ev_set_priority (&ctx->tw, EV_MINPRI); |
163 | ev_set_priority (&ctx->tw, EV_MINPRI); |
161 | } |
164 | } |