21
#include "qemu/osdep.h"
22
#include "io/channel-watch.h"
24
typedef struct QIOChannelFDSource QIOChannelFDSource;
25
struct QIOChannelFDSource {
29
GIOCondition condition;
34
typedef struct QIOChannelSocketSource QIOChannelSocketSource;
35
struct QIOChannelSocketSource {
41
GIOCondition condition;
47
typedef struct QIOChannelFDPairSource QIOChannelFDPairSource;
48
struct QIOChannelFDPairSource {
53
GIOCondition condition;
58
qio_channel_fd_source_prepare(GSource *source G_GNUC_UNUSED,
68
qio_channel_fd_source_check(GSource *source)
70
QIOChannelFDSource *ssource = (QIOChannelFDSource *)source;
72
return ssource->fd.revents & ssource->condition;
77
qio_channel_fd_source_dispatch(GSource *source,
81
QIOChannelFunc func = (QIOChannelFunc)callback;
82
QIOChannelFDSource *ssource = (QIOChannelFDSource *)source;
84
return (*func)(ssource->ioc,
85
ssource->fd.revents & ssource->condition,
91
qio_channel_fd_source_finalize(GSource *source)
93
QIOChannelFDSource *ssource = (QIOChannelFDSource *)source;
95
object_unref(OBJECT(ssource->ioc));
101
qio_channel_socket_source_prepare(GSource *source G_GNUC_UNUSED,
115
qio_channel_socket_source_check(GSource *source)
117
static struct timeval tv0;
118
QIOChannelSocketSource *ssource = (QIOChannelSocketSource *)source;
119
fd_set rfds, wfds, xfds;
121
if (!ssource->condition) {
128
if (ssource->condition & G_IO_IN) {
129
FD_SET(ssource->socket, &rfds);
131
if (ssource->condition & G_IO_OUT) {
132
FD_SET(ssource->socket, &wfds);
134
if (ssource->condition & G_IO_PRI) {
135
FD_SET(ssource->socket, &xfds);
137
ssource->revents = 0;
138
if (select(0, &rfds, &wfds, &xfds, &tv0) == 0) {
142
if (FD_ISSET(ssource->socket, &rfds)) {
143
ssource->revents |= G_IO_IN;
145
if (FD_ISSET(ssource->socket, &wfds)) {
146
ssource->revents |= G_IO_OUT;
148
if (FD_ISSET(ssource->socket, &xfds)) {
149
ssource->revents |= G_IO_PRI;
152
return ssource->revents;
157
qio_channel_socket_source_dispatch(GSource *source,
158
GSourceFunc callback,
161
QIOChannelFunc func = (QIOChannelFunc)callback;
162
QIOChannelSocketSource *ssource = (QIOChannelSocketSource *)source;
164
return (*func)(ssource->ioc, ssource->revents, user_data);
169
qio_channel_socket_source_finalize(GSource *source)
171
QIOChannelSocketSource *ssource = (QIOChannelSocketSource *)source;
173
object_unref(OBJECT(ssource->ioc));
177
GSourceFuncs qio_channel_socket_source_funcs = {
178
qio_channel_socket_source_prepare,
179
qio_channel_socket_source_check,
180
qio_channel_socket_source_dispatch,
181
qio_channel_socket_source_finalize
187
qio_channel_fd_pair_source_prepare(GSource *source G_GNUC_UNUSED,
197
qio_channel_fd_pair_source_check(GSource *source)
199
QIOChannelFDPairSource *ssource = (QIOChannelFDPairSource *)source;
200
GIOCondition poll_condition = ssource->fdread.revents |
201
ssource->fdwrite.revents;
203
return poll_condition & ssource->condition;
208
qio_channel_fd_pair_source_dispatch(GSource *source,
209
GSourceFunc callback,
212
QIOChannelFunc func = (QIOChannelFunc)callback;
213
QIOChannelFDPairSource *ssource = (QIOChannelFDPairSource *)source;
214
GIOCondition poll_condition = ssource->fdread.revents |
215
ssource->fdwrite.revents;
217
return (*func)(ssource->ioc,
218
poll_condition & ssource->condition,
224
qio_channel_fd_pair_source_finalize(GSource *source)
226
QIOChannelFDPairSource *ssource = (QIOChannelFDPairSource *)source;
228
object_unref(OBJECT(ssource->ioc));
232
GSourceFuncs qio_channel_fd_source_funcs = {
233
qio_channel_fd_source_prepare,
234
qio_channel_fd_source_check,
235
qio_channel_fd_source_dispatch,
236
qio_channel_fd_source_finalize
240
GSourceFuncs qio_channel_fd_pair_source_funcs = {
241
qio_channel_fd_pair_source_prepare,
242
qio_channel_fd_pair_source_check,
243
qio_channel_fd_pair_source_dispatch,
244
qio_channel_fd_pair_source_finalize
248
GSource *qio_channel_create_fd_watch(QIOChannel *ioc,
250
GIOCondition condition)
253
QIOChannelFDSource *ssource;
255
source = g_source_new(&qio_channel_fd_source_funcs,
256
sizeof(QIOChannelFDSource));
257
ssource = (QIOChannelFDSource *)source;
260
object_ref(OBJECT(ioc));
262
ssource->condition = condition;
265
ssource->fd.fd = (gint64)_get_osfhandle(fd);
269
ssource->fd.events = condition;
271
g_source_add_poll(source, &ssource->fd);
277
GSource *qio_channel_create_socket_watch(QIOChannel *ioc,
279
GIOCondition condition)
282
QIOChannelSocketSource *ssource;
284
qemu_socket_select(sockfd, ioc->event,
285
FD_READ | FD_ACCEPT | FD_CLOSE |
286
FD_CONNECT | FD_WRITE | FD_OOB, NULL);
288
source = g_source_new(&qio_channel_socket_source_funcs,
289
sizeof(QIOChannelSocketSource));
290
ssource = (QIOChannelSocketSource *)source;
293
object_ref(OBJECT(ioc));
295
ssource->condition = condition;
296
ssource->socket = _get_osfhandle(sockfd);
297
ssource->revents = 0;
299
ssource->fd.fd = (gintptr)ioc->event;
300
ssource->fd.events = G_IO_IN;
302
g_source_add_poll(source, &ssource->fd);
307
GSource *qio_channel_create_socket_watch(QIOChannel *ioc,
309
GIOCondition condition)
311
return qio_channel_create_fd_watch(ioc, socket, condition);
315
GSource *qio_channel_create_fd_pair_watch(QIOChannel *ioc,
318
GIOCondition condition)
321
QIOChannelFDPairSource *ssource;
323
source = g_source_new(&qio_channel_fd_pair_source_funcs,
324
sizeof(QIOChannelFDPairSource));
325
ssource = (QIOChannelFDPairSource *)source;
328
object_ref(OBJECT(ioc));
330
ssource->condition = condition;
333
ssource->fdread.fd = (gint64)_get_osfhandle(fdread);
334
ssource->fdwrite.fd = (gint64)_get_osfhandle(fdwrite);
336
ssource->fdread.fd = fdread;
337
ssource->fdwrite.fd = fdwrite;
340
ssource->fdread.events = condition & G_IO_IN;
341
ssource->fdwrite.events = condition & G_IO_OUT;
343
g_source_add_poll(source, &ssource->fdread);
344
g_source_add_poll(source, &ssource->fdwrite);