xref: /openbmc/qemu/io/channel-watch.c (revision 284c52eec2d0a1b9c47f06c3eee46762c5fc0915)
11c809fa0SDaniel P. Berrange /*
21c809fa0SDaniel P. Berrange  * QEMU I/O channels watch helper APIs
31c809fa0SDaniel P. Berrange  *
41c809fa0SDaniel P. Berrange  * Copyright (c) 2015 Red Hat, Inc.
51c809fa0SDaniel P. Berrange  *
61c809fa0SDaniel P. Berrange  * This library is free software; you can redistribute it and/or
71c809fa0SDaniel P. Berrange  * modify it under the terms of the GNU Lesser General Public
81c809fa0SDaniel P. Berrange  * License as published by the Free Software Foundation; either
9c8198bd5SChetan Pant  * version 2.1 of the License, or (at your option) any later version.
101c809fa0SDaniel P. Berrange  *
111c809fa0SDaniel P. Berrange  * This library is distributed in the hope that it will be useful,
121c809fa0SDaniel P. Berrange  * but WITHOUT ANY WARRANTY; without even the implied warranty of
131c809fa0SDaniel P. Berrange  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
141c809fa0SDaniel P. Berrange  * Lesser General Public License for more details.
151c809fa0SDaniel P. Berrange  *
161c809fa0SDaniel P. Berrange  * You should have received a copy of the GNU Lesser General Public
171c809fa0SDaniel P. Berrange  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
181c809fa0SDaniel P. Berrange  *
191c809fa0SDaniel P. Berrange  */
201c809fa0SDaniel P. Berrange 
21cae9fc56SPeter Maydell #include "qemu/osdep.h"
221c809fa0SDaniel P. Berrange #include "io/channel-watch.h"
231c809fa0SDaniel P. Berrange 
241c809fa0SDaniel P. Berrange typedef struct QIOChannelFDSource QIOChannelFDSource;
251c809fa0SDaniel P. Berrange struct QIOChannelFDSource {
261c809fa0SDaniel P. Berrange     GSource parent;
271c809fa0SDaniel P. Berrange     GPollFD fd;
281c809fa0SDaniel P. Berrange     QIOChannel *ioc;
291c809fa0SDaniel P. Berrange     GIOCondition condition;
301c809fa0SDaniel P. Berrange };
311c809fa0SDaniel P. Berrange 
321c809fa0SDaniel P. Berrange 
33a5897205SPaolo Bonzini #ifdef CONFIG_WIN32
34a5897205SPaolo Bonzini typedef struct QIOChannelSocketSource QIOChannelSocketSource;
35a5897205SPaolo Bonzini struct QIOChannelSocketSource {
36a5897205SPaolo Bonzini     GSource parent;
37a5897205SPaolo Bonzini     GPollFD fd;
38a5897205SPaolo Bonzini     QIOChannel *ioc;
39a5897205SPaolo Bonzini     SOCKET socket;
40a5897205SPaolo Bonzini     int revents;
41a5897205SPaolo Bonzini     GIOCondition condition;
42a5897205SPaolo Bonzini };
43a5897205SPaolo Bonzini 
44a5897205SPaolo Bonzini #endif
45a5897205SPaolo Bonzini 
46a5897205SPaolo Bonzini 
471c809fa0SDaniel P. Berrange typedef struct QIOChannelFDPairSource QIOChannelFDPairSource;
481c809fa0SDaniel P. Berrange struct QIOChannelFDPairSource {
491c809fa0SDaniel P. Berrange     GSource parent;
501c809fa0SDaniel P. Berrange     GPollFD fdread;
511c809fa0SDaniel P. Berrange     GPollFD fdwrite;
521c809fa0SDaniel P. Berrange     QIOChannel *ioc;
531c809fa0SDaniel P. Berrange     GIOCondition condition;
541c809fa0SDaniel P. Berrange };
551c809fa0SDaniel P. Berrange 
561c809fa0SDaniel P. Berrange 
571c809fa0SDaniel P. Berrange static gboolean
qio_channel_fd_source_prepare(GSource * source G_GNUC_UNUSED,gint * timeout)581c809fa0SDaniel P. Berrange qio_channel_fd_source_prepare(GSource *source G_GNUC_UNUSED,
591c809fa0SDaniel P. Berrange                               gint *timeout)
601c809fa0SDaniel P. Berrange {
611c809fa0SDaniel P. Berrange     *timeout = -1;
621c809fa0SDaniel P. Berrange 
631c809fa0SDaniel P. Berrange     return FALSE;
641c809fa0SDaniel P. Berrange }
651c809fa0SDaniel P. Berrange 
661c809fa0SDaniel P. Berrange 
671c809fa0SDaniel P. Berrange static gboolean
qio_channel_fd_source_check(GSource * source)681c809fa0SDaniel P. Berrange qio_channel_fd_source_check(GSource *source)
691c809fa0SDaniel P. Berrange {
701c809fa0SDaniel P. Berrange     QIOChannelFDSource *ssource = (QIOChannelFDSource *)source;
711c809fa0SDaniel P. Berrange 
721c809fa0SDaniel P. Berrange     return ssource->fd.revents & ssource->condition;
731c809fa0SDaniel P. Berrange }
741c809fa0SDaniel P. Berrange 
751c809fa0SDaniel P. Berrange 
761c809fa0SDaniel P. Berrange static gboolean
qio_channel_fd_source_dispatch(GSource * source,GSourceFunc callback,gpointer user_data)771c809fa0SDaniel P. Berrange qio_channel_fd_source_dispatch(GSource *source,
781c809fa0SDaniel P. Berrange                                GSourceFunc callback,
791c809fa0SDaniel P. Berrange                                gpointer user_data)
801c809fa0SDaniel P. Berrange {
811c809fa0SDaniel P. Berrange     QIOChannelFunc func = (QIOChannelFunc)callback;
821c809fa0SDaniel P. Berrange     QIOChannelFDSource *ssource = (QIOChannelFDSource *)source;
831c809fa0SDaniel P. Berrange 
841c809fa0SDaniel P. Berrange     return (*func)(ssource->ioc,
851c809fa0SDaniel P. Berrange                    ssource->fd.revents & ssource->condition,
861c809fa0SDaniel P. Berrange                    user_data);
871c809fa0SDaniel P. Berrange }
881c809fa0SDaniel P. Berrange 
891c809fa0SDaniel P. Berrange 
901c809fa0SDaniel P. Berrange static void
qio_channel_fd_source_finalize(GSource * source)911c809fa0SDaniel P. Berrange qio_channel_fd_source_finalize(GSource *source)
921c809fa0SDaniel P. Berrange {
931c809fa0SDaniel P. Berrange     QIOChannelFDSource *ssource = (QIOChannelFDSource *)source;
941c809fa0SDaniel P. Berrange 
951c809fa0SDaniel P. Berrange     object_unref(OBJECT(ssource->ioc));
961c809fa0SDaniel P. Berrange }
971c809fa0SDaniel P. Berrange 
981c809fa0SDaniel P. Berrange 
99a5897205SPaolo Bonzini #ifdef CONFIG_WIN32
100a5897205SPaolo Bonzini static gboolean
qio_channel_socket_source_prepare(GSource * source G_GNUC_UNUSED,gint * timeout)101a5897205SPaolo Bonzini qio_channel_socket_source_prepare(GSource *source G_GNUC_UNUSED,
102a5897205SPaolo Bonzini                                   gint *timeout)
103a5897205SPaolo Bonzini {
104a5897205SPaolo Bonzini     *timeout = -1;
105a5897205SPaolo Bonzini 
106a5897205SPaolo Bonzini     return FALSE;
107a5897205SPaolo Bonzini }
108a5897205SPaolo Bonzini 
109a5897205SPaolo Bonzini 
110a5897205SPaolo Bonzini /*
111a5897205SPaolo Bonzini  * NB, this impl only works when the socket is in non-blocking
112a5897205SPaolo Bonzini  * mode on Win32
113a5897205SPaolo Bonzini  */
114a5897205SPaolo Bonzini static gboolean
qio_channel_socket_source_check(GSource * source)115a5897205SPaolo Bonzini qio_channel_socket_source_check(GSource *source)
116a5897205SPaolo Bonzini {
117a5897205SPaolo Bonzini     static struct timeval tv0;
118a5897205SPaolo Bonzini     QIOChannelSocketSource *ssource = (QIOChannelSocketSource *)source;
119a5897205SPaolo Bonzini     fd_set rfds, wfds, xfds;
120a5897205SPaolo Bonzini 
121a5897205SPaolo Bonzini     if (!ssource->condition) {
122a5897205SPaolo Bonzini         return 0;
123a5897205SPaolo Bonzini     }
124a5897205SPaolo Bonzini 
125a5897205SPaolo Bonzini     FD_ZERO(&rfds);
126a5897205SPaolo Bonzini     FD_ZERO(&wfds);
127a5897205SPaolo Bonzini     FD_ZERO(&xfds);
128a5897205SPaolo Bonzini     if (ssource->condition & G_IO_IN) {
1296c822a03SBin Meng         FD_SET(ssource->socket, &rfds);
130a5897205SPaolo Bonzini     }
131a5897205SPaolo Bonzini     if (ssource->condition & G_IO_OUT) {
1326c822a03SBin Meng         FD_SET(ssource->socket, &wfds);
133a5897205SPaolo Bonzini     }
134a5897205SPaolo Bonzini     if (ssource->condition & G_IO_PRI) {
1356c822a03SBin Meng         FD_SET(ssource->socket, &xfds);
136a5897205SPaolo Bonzini     }
137a5897205SPaolo Bonzini     ssource->revents = 0;
138a5897205SPaolo Bonzini     if (select(0, &rfds, &wfds, &xfds, &tv0) == 0) {
139a5897205SPaolo Bonzini         return 0;
140a5897205SPaolo Bonzini     }
141a5897205SPaolo Bonzini 
142a5897205SPaolo Bonzini     if (FD_ISSET(ssource->socket, &rfds)) {
143a5897205SPaolo Bonzini         ssource->revents |= G_IO_IN;
144a5897205SPaolo Bonzini     }
145a5897205SPaolo Bonzini     if (FD_ISSET(ssource->socket, &wfds)) {
146a5897205SPaolo Bonzini         ssource->revents |= G_IO_OUT;
147a5897205SPaolo Bonzini     }
148a5897205SPaolo Bonzini     if (FD_ISSET(ssource->socket, &xfds)) {
149a5897205SPaolo Bonzini         ssource->revents |= G_IO_PRI;
150a5897205SPaolo Bonzini     }
151a5897205SPaolo Bonzini 
152a5897205SPaolo Bonzini     return ssource->revents;
153a5897205SPaolo Bonzini }
154a5897205SPaolo Bonzini 
155a5897205SPaolo Bonzini 
156a5897205SPaolo Bonzini static gboolean
qio_channel_socket_source_dispatch(GSource * source,GSourceFunc callback,gpointer user_data)157a5897205SPaolo Bonzini qio_channel_socket_source_dispatch(GSource *source,
158a5897205SPaolo Bonzini                                    GSourceFunc callback,
159a5897205SPaolo Bonzini                                    gpointer user_data)
160a5897205SPaolo Bonzini {
161a5897205SPaolo Bonzini     QIOChannelFunc func = (QIOChannelFunc)callback;
162a5897205SPaolo Bonzini     QIOChannelSocketSource *ssource = (QIOChannelSocketSource *)source;
163a5897205SPaolo Bonzini 
164a5897205SPaolo Bonzini     return (*func)(ssource->ioc, ssource->revents, user_data);
165a5897205SPaolo Bonzini }
166a5897205SPaolo Bonzini 
167a5897205SPaolo Bonzini 
168a5897205SPaolo Bonzini static void
qio_channel_socket_source_finalize(GSource * source)169a5897205SPaolo Bonzini qio_channel_socket_source_finalize(GSource *source)
170a5897205SPaolo Bonzini {
171a5897205SPaolo Bonzini     QIOChannelSocketSource *ssource = (QIOChannelSocketSource *)source;
172a5897205SPaolo Bonzini 
173a5897205SPaolo Bonzini     object_unref(OBJECT(ssource->ioc));
174a5897205SPaolo Bonzini }
175a5897205SPaolo Bonzini 
176a5897205SPaolo Bonzini 
177a5897205SPaolo Bonzini GSourceFuncs qio_channel_socket_source_funcs = {
178a5897205SPaolo Bonzini     qio_channel_socket_source_prepare,
179a5897205SPaolo Bonzini     qio_channel_socket_source_check,
180a5897205SPaolo Bonzini     qio_channel_socket_source_dispatch,
181a5897205SPaolo Bonzini     qio_channel_socket_source_finalize
182a5897205SPaolo Bonzini };
183a5897205SPaolo Bonzini #endif
184a5897205SPaolo Bonzini 
185a5897205SPaolo Bonzini 
1861c809fa0SDaniel P. Berrange static gboolean
qio_channel_fd_pair_source_prepare(GSource * source G_GNUC_UNUSED,gint * timeout)1871c809fa0SDaniel P. Berrange qio_channel_fd_pair_source_prepare(GSource *source G_GNUC_UNUSED,
1881c809fa0SDaniel P. Berrange                                    gint *timeout)
1891c809fa0SDaniel P. Berrange {
1901c809fa0SDaniel P. Berrange     *timeout = -1;
1911c809fa0SDaniel P. Berrange 
1921c809fa0SDaniel P. Berrange     return FALSE;
1931c809fa0SDaniel P. Berrange }
1941c809fa0SDaniel P. Berrange 
1951c809fa0SDaniel P. Berrange 
1961c809fa0SDaniel P. Berrange static gboolean
qio_channel_fd_pair_source_check(GSource * source)1971c809fa0SDaniel P. Berrange qio_channel_fd_pair_source_check(GSource *source)
1981c809fa0SDaniel P. Berrange {
1991c809fa0SDaniel P. Berrange     QIOChannelFDPairSource *ssource = (QIOChannelFDPairSource *)source;
2001c809fa0SDaniel P. Berrange     GIOCondition poll_condition = ssource->fdread.revents |
2011c809fa0SDaniel P. Berrange         ssource->fdwrite.revents;
2021c809fa0SDaniel P. Berrange 
2031c809fa0SDaniel P. Berrange     return poll_condition & ssource->condition;
2041c809fa0SDaniel P. Berrange }
2051c809fa0SDaniel P. Berrange 
2061c809fa0SDaniel P. Berrange 
2071c809fa0SDaniel P. Berrange static gboolean
qio_channel_fd_pair_source_dispatch(GSource * source,GSourceFunc callback,gpointer user_data)2081c809fa0SDaniel P. Berrange qio_channel_fd_pair_source_dispatch(GSource *source,
2091c809fa0SDaniel P. Berrange                                     GSourceFunc callback,
2101c809fa0SDaniel P. Berrange                                     gpointer user_data)
2111c809fa0SDaniel P. Berrange {
2121c809fa0SDaniel P. Berrange     QIOChannelFunc func = (QIOChannelFunc)callback;
2131c809fa0SDaniel P. Berrange     QIOChannelFDPairSource *ssource = (QIOChannelFDPairSource *)source;
2141c809fa0SDaniel P. Berrange     GIOCondition poll_condition = ssource->fdread.revents |
2151c809fa0SDaniel P. Berrange         ssource->fdwrite.revents;
2161c809fa0SDaniel P. Berrange 
2171c809fa0SDaniel P. Berrange     return (*func)(ssource->ioc,
2181c809fa0SDaniel P. Berrange                    poll_condition & ssource->condition,
2191c809fa0SDaniel P. Berrange                    user_data);
2201c809fa0SDaniel P. Berrange }
2211c809fa0SDaniel P. Berrange 
2221c809fa0SDaniel P. Berrange 
2231c809fa0SDaniel P. Berrange static void
qio_channel_fd_pair_source_finalize(GSource * source)2241c809fa0SDaniel P. Berrange qio_channel_fd_pair_source_finalize(GSource *source)
2251c809fa0SDaniel P. Berrange {
2261c809fa0SDaniel P. Berrange     QIOChannelFDPairSource *ssource = (QIOChannelFDPairSource *)source;
2271c809fa0SDaniel P. Berrange 
2281c809fa0SDaniel P. Berrange     object_unref(OBJECT(ssource->ioc));
2291c809fa0SDaniel P. Berrange }
2301c809fa0SDaniel P. Berrange 
2311c809fa0SDaniel P. Berrange 
2321c809fa0SDaniel P. Berrange GSourceFuncs qio_channel_fd_source_funcs = {
2331c809fa0SDaniel P. Berrange     qio_channel_fd_source_prepare,
2341c809fa0SDaniel P. Berrange     qio_channel_fd_source_check,
2351c809fa0SDaniel P. Berrange     qio_channel_fd_source_dispatch,
2361c809fa0SDaniel P. Berrange     qio_channel_fd_source_finalize
2371c809fa0SDaniel P. Berrange };
2381c809fa0SDaniel P. Berrange 
2391c809fa0SDaniel P. Berrange 
2401c809fa0SDaniel P. Berrange GSourceFuncs qio_channel_fd_pair_source_funcs = {
2411c809fa0SDaniel P. Berrange     qio_channel_fd_pair_source_prepare,
2421c809fa0SDaniel P. Berrange     qio_channel_fd_pair_source_check,
2431c809fa0SDaniel P. Berrange     qio_channel_fd_pair_source_dispatch,
2441c809fa0SDaniel P. Berrange     qio_channel_fd_pair_source_finalize
2451c809fa0SDaniel P. Berrange };
2461c809fa0SDaniel P. Berrange 
2471c809fa0SDaniel P. Berrange 
qio_channel_create_fd_watch(QIOChannel * ioc,int fd,GIOCondition condition)2481c809fa0SDaniel P. Berrange GSource *qio_channel_create_fd_watch(QIOChannel *ioc,
2491c809fa0SDaniel P. Berrange                                      int fd,
2501c809fa0SDaniel P. Berrange                                      GIOCondition condition)
2511c809fa0SDaniel P. Berrange {
2521c809fa0SDaniel P. Berrange     GSource *source;
2531c809fa0SDaniel P. Berrange     QIOChannelFDSource *ssource;
2541c809fa0SDaniel P. Berrange 
2551c809fa0SDaniel P. Berrange     source = g_source_new(&qio_channel_fd_source_funcs,
2561c809fa0SDaniel P. Berrange                           sizeof(QIOChannelFDSource));
2571c809fa0SDaniel P. Berrange     ssource = (QIOChannelFDSource *)source;
2581c809fa0SDaniel P. Berrange 
2591c809fa0SDaniel P. Berrange     ssource->ioc = ioc;
2601c809fa0SDaniel P. Berrange     object_ref(OBJECT(ioc));
2611c809fa0SDaniel P. Berrange 
2621c809fa0SDaniel P. Berrange     ssource->condition = condition;
2631c809fa0SDaniel P. Berrange 
264e560d141SPaolo Bonzini #ifdef CONFIG_WIN32
265e560d141SPaolo Bonzini     ssource->fd.fd = (gint64)_get_osfhandle(fd);
266e560d141SPaolo Bonzini #else
2671c809fa0SDaniel P. Berrange     ssource->fd.fd = fd;
268e560d141SPaolo Bonzini #endif
2691c809fa0SDaniel P. Berrange     ssource->fd.events = condition;
2701c809fa0SDaniel P. Berrange 
2711c809fa0SDaniel P. Berrange     g_source_add_poll(source, &ssource->fd);
2721c809fa0SDaniel P. Berrange 
2731c809fa0SDaniel P. Berrange     return source;
2741c809fa0SDaniel P. Berrange }
2751c809fa0SDaniel P. Berrange 
276b83b68a0SPaolo Bonzini #ifdef CONFIG_WIN32
qio_channel_create_socket_watch(QIOChannel * ioc,int sockfd,GIOCondition condition)277b83b68a0SPaolo Bonzini GSource *qio_channel_create_socket_watch(QIOChannel *ioc,
278*abe34282SMarc-André Lureau                                          int sockfd,
279b83b68a0SPaolo Bonzini                                          GIOCondition condition)
280b83b68a0SPaolo Bonzini {
281a5897205SPaolo Bonzini     GSource *source;
282a5897205SPaolo Bonzini     QIOChannelSocketSource *ssource;
283a5897205SPaolo Bonzini 
284*abe34282SMarc-André Lureau     qemu_socket_select(sockfd, ioc->event,
285bf88c124SPaolo Bonzini                        FD_READ | FD_ACCEPT | FD_CLOSE |
286f5fd677aSMarc-André Lureau                        FD_CONNECT | FD_WRITE | FD_OOB, NULL);
287bf88c124SPaolo Bonzini 
288a5897205SPaolo Bonzini     source = g_source_new(&qio_channel_socket_source_funcs,
289a5897205SPaolo Bonzini                           sizeof(QIOChannelSocketSource));
290a5897205SPaolo Bonzini     ssource = (QIOChannelSocketSource *)source;
291a5897205SPaolo Bonzini 
292a5897205SPaolo Bonzini     ssource->ioc = ioc;
293a5897205SPaolo Bonzini     object_ref(OBJECT(ioc));
294a5897205SPaolo Bonzini 
295a5897205SPaolo Bonzini     ssource->condition = condition;
296*abe34282SMarc-André Lureau     ssource->socket = _get_osfhandle(sockfd);
297a5897205SPaolo Bonzini     ssource->revents = 0;
298a5897205SPaolo Bonzini 
299a5897205SPaolo Bonzini     ssource->fd.fd = (gintptr)ioc->event;
300a5897205SPaolo Bonzini     ssource->fd.events = G_IO_IN;
301a5897205SPaolo Bonzini 
302a5897205SPaolo Bonzini     g_source_add_poll(source, &ssource->fd);
303a5897205SPaolo Bonzini 
304a5897205SPaolo Bonzini     return source;
305b83b68a0SPaolo Bonzini }
306b83b68a0SPaolo Bonzini #else
qio_channel_create_socket_watch(QIOChannel * ioc,int socket,GIOCondition condition)307b83b68a0SPaolo Bonzini GSource *qio_channel_create_socket_watch(QIOChannel *ioc,
308b83b68a0SPaolo Bonzini                                          int socket,
309b83b68a0SPaolo Bonzini                                          GIOCondition condition)
310b83b68a0SPaolo Bonzini {
311b83b68a0SPaolo Bonzini     return qio_channel_create_fd_watch(ioc, socket, condition);
312b83b68a0SPaolo Bonzini }
313b83b68a0SPaolo Bonzini #endif
3141c809fa0SDaniel P. Berrange 
qio_channel_create_fd_pair_watch(QIOChannel * ioc,int fdread,int fdwrite,GIOCondition condition)3151c809fa0SDaniel P. Berrange GSource *qio_channel_create_fd_pair_watch(QIOChannel *ioc,
3161c809fa0SDaniel P. Berrange                                           int fdread,
3171c809fa0SDaniel P. Berrange                                           int fdwrite,
3181c809fa0SDaniel P. Berrange                                           GIOCondition condition)
3191c809fa0SDaniel P. Berrange {
3201c809fa0SDaniel P. Berrange     GSource *source;
3211c809fa0SDaniel P. Berrange     QIOChannelFDPairSource *ssource;
3221c809fa0SDaniel P. Berrange 
3231c809fa0SDaniel P. Berrange     source = g_source_new(&qio_channel_fd_pair_source_funcs,
3241c809fa0SDaniel P. Berrange                           sizeof(QIOChannelFDPairSource));
3251c809fa0SDaniel P. Berrange     ssource = (QIOChannelFDPairSource *)source;
3261c809fa0SDaniel P. Berrange 
3271c809fa0SDaniel P. Berrange     ssource->ioc = ioc;
3281c809fa0SDaniel P. Berrange     object_ref(OBJECT(ioc));
3291c809fa0SDaniel P. Berrange 
3301c809fa0SDaniel P. Berrange     ssource->condition = condition;
3311c809fa0SDaniel P. Berrange 
332e560d141SPaolo Bonzini #ifdef CONFIG_WIN32
333e560d141SPaolo Bonzini     ssource->fdread.fd = (gint64)_get_osfhandle(fdread);
334e560d141SPaolo Bonzini     ssource->fdwrite.fd = (gint64)_get_osfhandle(fdwrite);
335e560d141SPaolo Bonzini #else
3361c809fa0SDaniel P. Berrange     ssource->fdread.fd = fdread;
3371c809fa0SDaniel P. Berrange     ssource->fdwrite.fd = fdwrite;
338e560d141SPaolo Bonzini #endif
339e560d141SPaolo Bonzini 
340e560d141SPaolo Bonzini     ssource->fdread.events = condition & G_IO_IN;
3411c809fa0SDaniel P. Berrange     ssource->fdwrite.events = condition & G_IO_OUT;
3421c809fa0SDaniel P. Berrange 
3431c809fa0SDaniel P. Berrange     g_source_add_poll(source, &ssource->fdread);
3441c809fa0SDaniel P. Berrange     g_source_add_poll(source, &ssource->fdwrite);
3451c809fa0SDaniel P. Berrange 
3461c809fa0SDaniel P. Berrange     return source;
3471c809fa0SDaniel P. Berrange }
348