xref: /qemu/io/channel-watch.c (revision 1c809fa01df0c638417480dfd446415615bfd217)
1*1c809fa0SDaniel P. Berrange /*
2*1c809fa0SDaniel P. Berrange  * QEMU I/O channels watch helper APIs
3*1c809fa0SDaniel P. Berrange  *
4*1c809fa0SDaniel P. Berrange  * Copyright (c) 2015 Red Hat, Inc.
5*1c809fa0SDaniel P. Berrange  *
6*1c809fa0SDaniel P. Berrange  * This library is free software; you can redistribute it and/or
7*1c809fa0SDaniel P. Berrange  * modify it under the terms of the GNU Lesser General Public
8*1c809fa0SDaniel P. Berrange  * License as published by the Free Software Foundation; either
9*1c809fa0SDaniel P. Berrange  * version 2 of the License, or (at your option) any later version.
10*1c809fa0SDaniel P. Berrange  *
11*1c809fa0SDaniel P. Berrange  * This library is distributed in the hope that it will be useful,
12*1c809fa0SDaniel P. Berrange  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13*1c809fa0SDaniel P. Berrange  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14*1c809fa0SDaniel P. Berrange  * Lesser General Public License for more details.
15*1c809fa0SDaniel P. Berrange  *
16*1c809fa0SDaniel P. Berrange  * You should have received a copy of the GNU Lesser General Public
17*1c809fa0SDaniel P. Berrange  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
18*1c809fa0SDaniel P. Berrange  *
19*1c809fa0SDaniel P. Berrange  */
20*1c809fa0SDaniel P. Berrange 
21*1c809fa0SDaniel P. Berrange #include "io/channel-watch.h"
22*1c809fa0SDaniel P. Berrange 
23*1c809fa0SDaniel P. Berrange typedef struct QIOChannelFDSource QIOChannelFDSource;
24*1c809fa0SDaniel P. Berrange struct QIOChannelFDSource {
25*1c809fa0SDaniel P. Berrange     GSource parent;
26*1c809fa0SDaniel P. Berrange     GPollFD fd;
27*1c809fa0SDaniel P. Berrange     QIOChannel *ioc;
28*1c809fa0SDaniel P. Berrange     GIOCondition condition;
29*1c809fa0SDaniel P. Berrange };
30*1c809fa0SDaniel P. Berrange 
31*1c809fa0SDaniel P. Berrange 
32*1c809fa0SDaniel P. Berrange typedef struct QIOChannelFDPairSource QIOChannelFDPairSource;
33*1c809fa0SDaniel P. Berrange struct QIOChannelFDPairSource {
34*1c809fa0SDaniel P. Berrange     GSource parent;
35*1c809fa0SDaniel P. Berrange     GPollFD fdread;
36*1c809fa0SDaniel P. Berrange     GPollFD fdwrite;
37*1c809fa0SDaniel P. Berrange     QIOChannel *ioc;
38*1c809fa0SDaniel P. Berrange     GIOCondition condition;
39*1c809fa0SDaniel P. Berrange };
40*1c809fa0SDaniel P. Berrange 
41*1c809fa0SDaniel P. Berrange 
42*1c809fa0SDaniel P. Berrange static gboolean
43*1c809fa0SDaniel P. Berrange qio_channel_fd_source_prepare(GSource *source G_GNUC_UNUSED,
44*1c809fa0SDaniel P. Berrange                               gint *timeout)
45*1c809fa0SDaniel P. Berrange {
46*1c809fa0SDaniel P. Berrange     *timeout = -1;
47*1c809fa0SDaniel P. Berrange 
48*1c809fa0SDaniel P. Berrange     return FALSE;
49*1c809fa0SDaniel P. Berrange }
50*1c809fa0SDaniel P. Berrange 
51*1c809fa0SDaniel P. Berrange 
52*1c809fa0SDaniel P. Berrange static gboolean
53*1c809fa0SDaniel P. Berrange qio_channel_fd_source_check(GSource *source)
54*1c809fa0SDaniel P. Berrange {
55*1c809fa0SDaniel P. Berrange     QIOChannelFDSource *ssource = (QIOChannelFDSource *)source;
56*1c809fa0SDaniel P. Berrange 
57*1c809fa0SDaniel P. Berrange     return ssource->fd.revents & ssource->condition;
58*1c809fa0SDaniel P. Berrange }
59*1c809fa0SDaniel P. Berrange 
60*1c809fa0SDaniel P. Berrange 
61*1c809fa0SDaniel P. Berrange static gboolean
62*1c809fa0SDaniel P. Berrange qio_channel_fd_source_dispatch(GSource *source,
63*1c809fa0SDaniel P. Berrange                                GSourceFunc callback,
64*1c809fa0SDaniel P. Berrange                                gpointer user_data)
65*1c809fa0SDaniel P. Berrange {
66*1c809fa0SDaniel P. Berrange     QIOChannelFunc func = (QIOChannelFunc)callback;
67*1c809fa0SDaniel P. Berrange     QIOChannelFDSource *ssource = (QIOChannelFDSource *)source;
68*1c809fa0SDaniel P. Berrange 
69*1c809fa0SDaniel P. Berrange     return (*func)(ssource->ioc,
70*1c809fa0SDaniel P. Berrange                    ssource->fd.revents & ssource->condition,
71*1c809fa0SDaniel P. Berrange                    user_data);
72*1c809fa0SDaniel P. Berrange }
73*1c809fa0SDaniel P. Berrange 
74*1c809fa0SDaniel P. Berrange 
75*1c809fa0SDaniel P. Berrange static void
76*1c809fa0SDaniel P. Berrange qio_channel_fd_source_finalize(GSource *source)
77*1c809fa0SDaniel P. Berrange {
78*1c809fa0SDaniel P. Berrange     QIOChannelFDSource *ssource = (QIOChannelFDSource *)source;
79*1c809fa0SDaniel P. Berrange 
80*1c809fa0SDaniel P. Berrange     object_unref(OBJECT(ssource->ioc));
81*1c809fa0SDaniel P. Berrange }
82*1c809fa0SDaniel P. Berrange 
83*1c809fa0SDaniel P. Berrange 
84*1c809fa0SDaniel P. Berrange static gboolean
85*1c809fa0SDaniel P. Berrange qio_channel_fd_pair_source_prepare(GSource *source G_GNUC_UNUSED,
86*1c809fa0SDaniel P. Berrange                                    gint *timeout)
87*1c809fa0SDaniel P. Berrange {
88*1c809fa0SDaniel P. Berrange     *timeout = -1;
89*1c809fa0SDaniel P. Berrange 
90*1c809fa0SDaniel P. Berrange     return FALSE;
91*1c809fa0SDaniel P. Berrange }
92*1c809fa0SDaniel P. Berrange 
93*1c809fa0SDaniel P. Berrange 
94*1c809fa0SDaniel P. Berrange static gboolean
95*1c809fa0SDaniel P. Berrange qio_channel_fd_pair_source_check(GSource *source)
96*1c809fa0SDaniel P. Berrange {
97*1c809fa0SDaniel P. Berrange     QIOChannelFDPairSource *ssource = (QIOChannelFDPairSource *)source;
98*1c809fa0SDaniel P. Berrange     GIOCondition poll_condition = ssource->fdread.revents |
99*1c809fa0SDaniel P. Berrange         ssource->fdwrite.revents;
100*1c809fa0SDaniel P. Berrange 
101*1c809fa0SDaniel P. Berrange     return poll_condition & ssource->condition;
102*1c809fa0SDaniel P. Berrange }
103*1c809fa0SDaniel P. Berrange 
104*1c809fa0SDaniel P. Berrange 
105*1c809fa0SDaniel P. Berrange static gboolean
106*1c809fa0SDaniel P. Berrange qio_channel_fd_pair_source_dispatch(GSource *source,
107*1c809fa0SDaniel P. Berrange                                     GSourceFunc callback,
108*1c809fa0SDaniel P. Berrange                                     gpointer user_data)
109*1c809fa0SDaniel P. Berrange {
110*1c809fa0SDaniel P. Berrange     QIOChannelFunc func = (QIOChannelFunc)callback;
111*1c809fa0SDaniel P. Berrange     QIOChannelFDPairSource *ssource = (QIOChannelFDPairSource *)source;
112*1c809fa0SDaniel P. Berrange     GIOCondition poll_condition = ssource->fdread.revents |
113*1c809fa0SDaniel P. Berrange         ssource->fdwrite.revents;
114*1c809fa0SDaniel P. Berrange 
115*1c809fa0SDaniel P. Berrange     return (*func)(ssource->ioc,
116*1c809fa0SDaniel P. Berrange                    poll_condition & ssource->condition,
117*1c809fa0SDaniel P. Berrange                    user_data);
118*1c809fa0SDaniel P. Berrange }
119*1c809fa0SDaniel P. Berrange 
120*1c809fa0SDaniel P. Berrange 
121*1c809fa0SDaniel P. Berrange static void
122*1c809fa0SDaniel P. Berrange qio_channel_fd_pair_source_finalize(GSource *source)
123*1c809fa0SDaniel P. Berrange {
124*1c809fa0SDaniel P. Berrange     QIOChannelFDPairSource *ssource = (QIOChannelFDPairSource *)source;
125*1c809fa0SDaniel P. Berrange 
126*1c809fa0SDaniel P. Berrange     object_unref(OBJECT(ssource->ioc));
127*1c809fa0SDaniel P. Berrange }
128*1c809fa0SDaniel P. Berrange 
129*1c809fa0SDaniel P. Berrange 
130*1c809fa0SDaniel P. Berrange GSourceFuncs qio_channel_fd_source_funcs = {
131*1c809fa0SDaniel P. Berrange     qio_channel_fd_source_prepare,
132*1c809fa0SDaniel P. Berrange     qio_channel_fd_source_check,
133*1c809fa0SDaniel P. Berrange     qio_channel_fd_source_dispatch,
134*1c809fa0SDaniel P. Berrange     qio_channel_fd_source_finalize
135*1c809fa0SDaniel P. Berrange };
136*1c809fa0SDaniel P. Berrange 
137*1c809fa0SDaniel P. Berrange 
138*1c809fa0SDaniel P. Berrange GSourceFuncs qio_channel_fd_pair_source_funcs = {
139*1c809fa0SDaniel P. Berrange     qio_channel_fd_pair_source_prepare,
140*1c809fa0SDaniel P. Berrange     qio_channel_fd_pair_source_check,
141*1c809fa0SDaniel P. Berrange     qio_channel_fd_pair_source_dispatch,
142*1c809fa0SDaniel P. Berrange     qio_channel_fd_pair_source_finalize
143*1c809fa0SDaniel P. Berrange };
144*1c809fa0SDaniel P. Berrange 
145*1c809fa0SDaniel P. Berrange 
146*1c809fa0SDaniel P. Berrange GSource *qio_channel_create_fd_watch(QIOChannel *ioc,
147*1c809fa0SDaniel P. Berrange                                      int fd,
148*1c809fa0SDaniel P. Berrange                                      GIOCondition condition)
149*1c809fa0SDaniel P. Berrange {
150*1c809fa0SDaniel P. Berrange     GSource *source;
151*1c809fa0SDaniel P. Berrange     QIOChannelFDSource *ssource;
152*1c809fa0SDaniel P. Berrange 
153*1c809fa0SDaniel P. Berrange     source = g_source_new(&qio_channel_fd_source_funcs,
154*1c809fa0SDaniel P. Berrange                           sizeof(QIOChannelFDSource));
155*1c809fa0SDaniel P. Berrange     ssource = (QIOChannelFDSource *)source;
156*1c809fa0SDaniel P. Berrange 
157*1c809fa0SDaniel P. Berrange     ssource->ioc = ioc;
158*1c809fa0SDaniel P. Berrange     object_ref(OBJECT(ioc));
159*1c809fa0SDaniel P. Berrange 
160*1c809fa0SDaniel P. Berrange     ssource->condition = condition;
161*1c809fa0SDaniel P. Berrange 
162*1c809fa0SDaniel P. Berrange     ssource->fd.fd = fd;
163*1c809fa0SDaniel P. Berrange     ssource->fd.events = condition;
164*1c809fa0SDaniel P. Berrange 
165*1c809fa0SDaniel P. Berrange     g_source_add_poll(source, &ssource->fd);
166*1c809fa0SDaniel P. Berrange 
167*1c809fa0SDaniel P. Berrange     return source;
168*1c809fa0SDaniel P. Berrange }
169*1c809fa0SDaniel P. Berrange 
170*1c809fa0SDaniel P. Berrange 
171*1c809fa0SDaniel P. Berrange GSource *qio_channel_create_fd_pair_watch(QIOChannel *ioc,
172*1c809fa0SDaniel P. Berrange                                           int fdread,
173*1c809fa0SDaniel P. Berrange                                           int fdwrite,
174*1c809fa0SDaniel P. Berrange                                           GIOCondition condition)
175*1c809fa0SDaniel P. Berrange {
176*1c809fa0SDaniel P. Berrange     GSource *source;
177*1c809fa0SDaniel P. Berrange     QIOChannelFDPairSource *ssource;
178*1c809fa0SDaniel P. Berrange 
179*1c809fa0SDaniel P. Berrange     source = g_source_new(&qio_channel_fd_pair_source_funcs,
180*1c809fa0SDaniel P. Berrange                           sizeof(QIOChannelFDPairSource));
181*1c809fa0SDaniel P. Berrange     ssource = (QIOChannelFDPairSource *)source;
182*1c809fa0SDaniel P. Berrange 
183*1c809fa0SDaniel P. Berrange     ssource->ioc = ioc;
184*1c809fa0SDaniel P. Berrange     object_ref(OBJECT(ioc));
185*1c809fa0SDaniel P. Berrange 
186*1c809fa0SDaniel P. Berrange     ssource->condition = condition;
187*1c809fa0SDaniel P. Berrange 
188*1c809fa0SDaniel P. Berrange     ssource->fdread.fd = fdread;
189*1c809fa0SDaniel P. Berrange     ssource->fdread.events = condition & G_IO_IN;
190*1c809fa0SDaniel P. Berrange 
191*1c809fa0SDaniel P. Berrange     ssource->fdwrite.fd = fdwrite;
192*1c809fa0SDaniel P. Berrange     ssource->fdwrite.events = condition & G_IO_OUT;
193*1c809fa0SDaniel P. Berrange 
194*1c809fa0SDaniel P. Berrange     g_source_add_poll(source, &ssource->fdread);
195*1c809fa0SDaniel P. Berrange     g_source_add_poll(source, &ssource->fdwrite);
196*1c809fa0SDaniel P. Berrange 
197*1c809fa0SDaniel P. Berrange     return source;
198*1c809fa0SDaniel P. Berrange }
199