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