xref: /qemu/io/channel-watch.c (revision b83b68a0132f43f3ebcb61c9237ec1090da58894)
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
91c809fa0SDaniel P. Berrange  * version 2 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 
331c809fa0SDaniel P. Berrange typedef struct QIOChannelFDPairSource QIOChannelFDPairSource;
341c809fa0SDaniel P. Berrange struct QIOChannelFDPairSource {
351c809fa0SDaniel P. Berrange     GSource parent;
361c809fa0SDaniel P. Berrange     GPollFD fdread;
371c809fa0SDaniel P. Berrange     GPollFD fdwrite;
381c809fa0SDaniel P. Berrange     QIOChannel *ioc;
391c809fa0SDaniel P. Berrange     GIOCondition condition;
401c809fa0SDaniel P. Berrange };
411c809fa0SDaniel P. Berrange 
421c809fa0SDaniel P. Berrange 
431c809fa0SDaniel P. Berrange static gboolean
441c809fa0SDaniel P. Berrange qio_channel_fd_source_prepare(GSource *source G_GNUC_UNUSED,
451c809fa0SDaniel P. Berrange                               gint *timeout)
461c809fa0SDaniel P. Berrange {
471c809fa0SDaniel P. Berrange     *timeout = -1;
481c809fa0SDaniel P. Berrange 
491c809fa0SDaniel P. Berrange     return FALSE;
501c809fa0SDaniel P. Berrange }
511c809fa0SDaniel P. Berrange 
521c809fa0SDaniel P. Berrange 
531c809fa0SDaniel P. Berrange static gboolean
541c809fa0SDaniel P. Berrange qio_channel_fd_source_check(GSource *source)
551c809fa0SDaniel P. Berrange {
561c809fa0SDaniel P. Berrange     QIOChannelFDSource *ssource = (QIOChannelFDSource *)source;
571c809fa0SDaniel P. Berrange 
581c809fa0SDaniel P. Berrange     return ssource->fd.revents & ssource->condition;
591c809fa0SDaniel P. Berrange }
601c809fa0SDaniel P. Berrange 
611c809fa0SDaniel P. Berrange 
621c809fa0SDaniel P. Berrange static gboolean
631c809fa0SDaniel P. Berrange qio_channel_fd_source_dispatch(GSource *source,
641c809fa0SDaniel P. Berrange                                GSourceFunc callback,
651c809fa0SDaniel P. Berrange                                gpointer user_data)
661c809fa0SDaniel P. Berrange {
671c809fa0SDaniel P. Berrange     QIOChannelFunc func = (QIOChannelFunc)callback;
681c809fa0SDaniel P. Berrange     QIOChannelFDSource *ssource = (QIOChannelFDSource *)source;
691c809fa0SDaniel P. Berrange 
701c809fa0SDaniel P. Berrange     return (*func)(ssource->ioc,
711c809fa0SDaniel P. Berrange                    ssource->fd.revents & ssource->condition,
721c809fa0SDaniel P. Berrange                    user_data);
731c809fa0SDaniel P. Berrange }
741c809fa0SDaniel P. Berrange 
751c809fa0SDaniel P. Berrange 
761c809fa0SDaniel P. Berrange static void
771c809fa0SDaniel P. Berrange qio_channel_fd_source_finalize(GSource *source)
781c809fa0SDaniel P. Berrange {
791c809fa0SDaniel P. Berrange     QIOChannelFDSource *ssource = (QIOChannelFDSource *)source;
801c809fa0SDaniel P. Berrange 
811c809fa0SDaniel P. Berrange     object_unref(OBJECT(ssource->ioc));
821c809fa0SDaniel P. Berrange }
831c809fa0SDaniel P. Berrange 
841c809fa0SDaniel P. Berrange 
851c809fa0SDaniel P. Berrange static gboolean
861c809fa0SDaniel P. Berrange qio_channel_fd_pair_source_prepare(GSource *source G_GNUC_UNUSED,
871c809fa0SDaniel P. Berrange                                    gint *timeout)
881c809fa0SDaniel P. Berrange {
891c809fa0SDaniel P. Berrange     *timeout = -1;
901c809fa0SDaniel P. Berrange 
911c809fa0SDaniel P. Berrange     return FALSE;
921c809fa0SDaniel P. Berrange }
931c809fa0SDaniel P. Berrange 
941c809fa0SDaniel P. Berrange 
951c809fa0SDaniel P. Berrange static gboolean
961c809fa0SDaniel P. Berrange qio_channel_fd_pair_source_check(GSource *source)
971c809fa0SDaniel P. Berrange {
981c809fa0SDaniel P. Berrange     QIOChannelFDPairSource *ssource = (QIOChannelFDPairSource *)source;
991c809fa0SDaniel P. Berrange     GIOCondition poll_condition = ssource->fdread.revents |
1001c809fa0SDaniel P. Berrange         ssource->fdwrite.revents;
1011c809fa0SDaniel P. Berrange 
1021c809fa0SDaniel P. Berrange     return poll_condition & ssource->condition;
1031c809fa0SDaniel P. Berrange }
1041c809fa0SDaniel P. Berrange 
1051c809fa0SDaniel P. Berrange 
1061c809fa0SDaniel P. Berrange static gboolean
1071c809fa0SDaniel P. Berrange qio_channel_fd_pair_source_dispatch(GSource *source,
1081c809fa0SDaniel P. Berrange                                     GSourceFunc callback,
1091c809fa0SDaniel P. Berrange                                     gpointer user_data)
1101c809fa0SDaniel P. Berrange {
1111c809fa0SDaniel P. Berrange     QIOChannelFunc func = (QIOChannelFunc)callback;
1121c809fa0SDaniel P. Berrange     QIOChannelFDPairSource *ssource = (QIOChannelFDPairSource *)source;
1131c809fa0SDaniel P. Berrange     GIOCondition poll_condition = ssource->fdread.revents |
1141c809fa0SDaniel P. Berrange         ssource->fdwrite.revents;
1151c809fa0SDaniel P. Berrange 
1161c809fa0SDaniel P. Berrange     return (*func)(ssource->ioc,
1171c809fa0SDaniel P. Berrange                    poll_condition & ssource->condition,
1181c809fa0SDaniel P. Berrange                    user_data);
1191c809fa0SDaniel P. Berrange }
1201c809fa0SDaniel P. Berrange 
1211c809fa0SDaniel P. Berrange 
1221c809fa0SDaniel P. Berrange static void
1231c809fa0SDaniel P. Berrange qio_channel_fd_pair_source_finalize(GSource *source)
1241c809fa0SDaniel P. Berrange {
1251c809fa0SDaniel P. Berrange     QIOChannelFDPairSource *ssource = (QIOChannelFDPairSource *)source;
1261c809fa0SDaniel P. Berrange 
1271c809fa0SDaniel P. Berrange     object_unref(OBJECT(ssource->ioc));
1281c809fa0SDaniel P. Berrange }
1291c809fa0SDaniel P. Berrange 
1301c809fa0SDaniel P. Berrange 
1311c809fa0SDaniel P. Berrange GSourceFuncs qio_channel_fd_source_funcs = {
1321c809fa0SDaniel P. Berrange     qio_channel_fd_source_prepare,
1331c809fa0SDaniel P. Berrange     qio_channel_fd_source_check,
1341c809fa0SDaniel P. Berrange     qio_channel_fd_source_dispatch,
1351c809fa0SDaniel P. Berrange     qio_channel_fd_source_finalize
1361c809fa0SDaniel P. Berrange };
1371c809fa0SDaniel P. Berrange 
1381c809fa0SDaniel P. Berrange 
1391c809fa0SDaniel P. Berrange GSourceFuncs qio_channel_fd_pair_source_funcs = {
1401c809fa0SDaniel P. Berrange     qio_channel_fd_pair_source_prepare,
1411c809fa0SDaniel P. Berrange     qio_channel_fd_pair_source_check,
1421c809fa0SDaniel P. Berrange     qio_channel_fd_pair_source_dispatch,
1431c809fa0SDaniel P. Berrange     qio_channel_fd_pair_source_finalize
1441c809fa0SDaniel P. Berrange };
1451c809fa0SDaniel P. Berrange 
1461c809fa0SDaniel P. Berrange 
1471c809fa0SDaniel P. Berrange GSource *qio_channel_create_fd_watch(QIOChannel *ioc,
1481c809fa0SDaniel P. Berrange                                      int fd,
1491c809fa0SDaniel P. Berrange                                      GIOCondition condition)
1501c809fa0SDaniel P. Berrange {
1511c809fa0SDaniel P. Berrange     GSource *source;
1521c809fa0SDaniel P. Berrange     QIOChannelFDSource *ssource;
1531c809fa0SDaniel P. Berrange 
1541c809fa0SDaniel P. Berrange     source = g_source_new(&qio_channel_fd_source_funcs,
1551c809fa0SDaniel P. Berrange                           sizeof(QIOChannelFDSource));
1561c809fa0SDaniel P. Berrange     ssource = (QIOChannelFDSource *)source;
1571c809fa0SDaniel P. Berrange 
1581c809fa0SDaniel P. Berrange     ssource->ioc = ioc;
1591c809fa0SDaniel P. Berrange     object_ref(OBJECT(ioc));
1601c809fa0SDaniel P. Berrange 
1611c809fa0SDaniel P. Berrange     ssource->condition = condition;
1621c809fa0SDaniel P. Berrange 
163e560d141SPaolo Bonzini #ifdef CONFIG_WIN32
164e560d141SPaolo Bonzini     ssource->fd.fd = (gint64)_get_osfhandle(fd);
165e560d141SPaolo Bonzini #else
1661c809fa0SDaniel P. Berrange     ssource->fd.fd = fd;
167e560d141SPaolo Bonzini #endif
1681c809fa0SDaniel P. Berrange     ssource->fd.events = condition;
1691c809fa0SDaniel P. Berrange 
1701c809fa0SDaniel P. Berrange     g_source_add_poll(source, &ssource->fd);
1711c809fa0SDaniel P. Berrange 
1721c809fa0SDaniel P. Berrange     return source;
1731c809fa0SDaniel P. Berrange }
1741c809fa0SDaniel P. Berrange 
175*b83b68a0SPaolo Bonzini #ifdef CONFIG_WIN32
176*b83b68a0SPaolo Bonzini GSource *qio_channel_create_socket_watch(QIOChannel *ioc,
177*b83b68a0SPaolo Bonzini                                          int socket,
178*b83b68a0SPaolo Bonzini                                          GIOCondition condition)
179*b83b68a0SPaolo Bonzini {
180*b83b68a0SPaolo Bonzini     abort();
181*b83b68a0SPaolo Bonzini }
182*b83b68a0SPaolo Bonzini #else
183*b83b68a0SPaolo Bonzini GSource *qio_channel_create_socket_watch(QIOChannel *ioc,
184*b83b68a0SPaolo Bonzini                                          int socket,
185*b83b68a0SPaolo Bonzini                                          GIOCondition condition)
186*b83b68a0SPaolo Bonzini {
187*b83b68a0SPaolo Bonzini     return qio_channel_create_fd_watch(ioc, socket, condition);
188*b83b68a0SPaolo Bonzini }
189*b83b68a0SPaolo Bonzini #endif
1901c809fa0SDaniel P. Berrange 
1911c809fa0SDaniel P. Berrange GSource *qio_channel_create_fd_pair_watch(QIOChannel *ioc,
1921c809fa0SDaniel P. Berrange                                           int fdread,
1931c809fa0SDaniel P. Berrange                                           int fdwrite,
1941c809fa0SDaniel P. Berrange                                           GIOCondition condition)
1951c809fa0SDaniel P. Berrange {
1961c809fa0SDaniel P. Berrange     GSource *source;
1971c809fa0SDaniel P. Berrange     QIOChannelFDPairSource *ssource;
1981c809fa0SDaniel P. Berrange 
1991c809fa0SDaniel P. Berrange     source = g_source_new(&qio_channel_fd_pair_source_funcs,
2001c809fa0SDaniel P. Berrange                           sizeof(QIOChannelFDPairSource));
2011c809fa0SDaniel P. Berrange     ssource = (QIOChannelFDPairSource *)source;
2021c809fa0SDaniel P. Berrange 
2031c809fa0SDaniel P. Berrange     ssource->ioc = ioc;
2041c809fa0SDaniel P. Berrange     object_ref(OBJECT(ioc));
2051c809fa0SDaniel P. Berrange 
2061c809fa0SDaniel P. Berrange     ssource->condition = condition;
2071c809fa0SDaniel P. Berrange 
208e560d141SPaolo Bonzini #ifdef CONFIG_WIN32
209e560d141SPaolo Bonzini     ssource->fdread.fd = (gint64)_get_osfhandle(fdread);
210e560d141SPaolo Bonzini     ssource->fdwrite.fd = (gint64)_get_osfhandle(fdwrite);
211e560d141SPaolo Bonzini #else
2121c809fa0SDaniel P. Berrange     ssource->fdread.fd = fdread;
2131c809fa0SDaniel P. Berrange     ssource->fdwrite.fd = fdwrite;
214e560d141SPaolo Bonzini #endif
215e560d141SPaolo Bonzini 
216e560d141SPaolo Bonzini     ssource->fdread.events = condition & G_IO_IN;
2171c809fa0SDaniel P. Berrange     ssource->fdwrite.events = condition & G_IO_OUT;
2181c809fa0SDaniel P. Berrange 
2191c809fa0SDaniel P. Berrange     g_source_add_poll(source, &ssource->fdread);
2201c809fa0SDaniel P. Berrange     g_source_add_poll(source, &ssource->fdwrite);
2211c809fa0SDaniel P. Berrange 
2221c809fa0SDaniel P. Berrange     return source;
2231c809fa0SDaniel P. Berrange }
224