4 * Copyright (c) 2015 Red Hat, Inc.
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.
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.
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/>.
21 #include "qemu/osdep.h"
22 #include "io/channel.h"
23 #include "qemu/coroutine.h"
25 bool qio_channel_has_feature(QIOChannel
*ioc
,
26 QIOChannelFeature feature
)
28 return ioc
->features
& (1 << feature
);
32 ssize_t
qio_channel_readv_full(QIOChannel
*ioc
,
33 const struct iovec
*iov
,
39 QIOChannelClass
*klass
= QIO_CHANNEL_GET_CLASS(ioc
);
42 !(ioc
->features
& (1 << QIO_CHANNEL_FEATURE_FD_PASS
))) {
43 error_setg_errno(errp
, EINVAL
,
44 "Channel does not support file descriptor passing");
48 return klass
->io_readv(ioc
, iov
, niov
, fds
, nfds
, errp
);
52 ssize_t
qio_channel_writev_full(QIOChannel
*ioc
,
53 const struct iovec
*iov
,
59 QIOChannelClass
*klass
= QIO_CHANNEL_GET_CLASS(ioc
);
62 !(ioc
->features
& (1 << QIO_CHANNEL_FEATURE_FD_PASS
))) {
63 error_setg_errno(errp
, EINVAL
,
64 "Channel does not support file descriptor passing");
68 return klass
->io_writev(ioc
, iov
, niov
, fds
, nfds
, errp
);
72 ssize_t
qio_channel_readv(QIOChannel
*ioc
,
73 const struct iovec
*iov
,
77 return qio_channel_readv_full(ioc
, iov
, niov
, NULL
, NULL
, errp
);
81 ssize_t
qio_channel_writev(QIOChannel
*ioc
,
82 const struct iovec
*iov
,
86 return qio_channel_writev_full(ioc
, iov
, niov
, NULL
, 0, errp
);
90 ssize_t
qio_channel_read(QIOChannel
*ioc
,
95 struct iovec iov
= { .iov_base
= buf
, .iov_len
= buflen
};
96 return qio_channel_readv_full(ioc
, &iov
, 1, NULL
, NULL
, errp
);
100 ssize_t
qio_channel_write(QIOChannel
*ioc
,
105 struct iovec iov
= { .iov_base
= (char *)buf
, .iov_len
= buflen
};
106 return qio_channel_writev_full(ioc
, &iov
, 1, NULL
, 0, errp
);
110 int qio_channel_set_blocking(QIOChannel
*ioc
,
114 QIOChannelClass
*klass
= QIO_CHANNEL_GET_CLASS(ioc
);
115 return klass
->io_set_blocking(ioc
, enabled
, errp
);
119 int qio_channel_close(QIOChannel
*ioc
,
122 QIOChannelClass
*klass
= QIO_CHANNEL_GET_CLASS(ioc
);
123 return klass
->io_close(ioc
, errp
);
127 GSource
*qio_channel_create_watch(QIOChannel
*ioc
,
128 GIOCondition condition
)
130 QIOChannelClass
*klass
= QIO_CHANNEL_GET_CLASS(ioc
);
131 return klass
->io_create_watch(ioc
, condition
);
135 guint
qio_channel_add_watch(QIOChannel
*ioc
,
136 GIOCondition condition
,
139 GDestroyNotify notify
)
144 source
= qio_channel_create_watch(ioc
, condition
);
146 g_source_set_callback(source
, (GSourceFunc
)func
, user_data
, notify
);
148 id
= g_source_attach(source
, NULL
);
149 g_source_unref(source
);
155 int qio_channel_shutdown(QIOChannel
*ioc
,
156 QIOChannelShutdown how
,
159 QIOChannelClass
*klass
= QIO_CHANNEL_GET_CLASS(ioc
);
161 if (!klass
->io_shutdown
) {
162 error_setg(errp
, "Data path shutdown not supported");
166 return klass
->io_shutdown(ioc
, how
, errp
);
170 void qio_channel_set_delay(QIOChannel
*ioc
,
173 QIOChannelClass
*klass
= QIO_CHANNEL_GET_CLASS(ioc
);
175 if (klass
->io_set_delay
) {
176 klass
->io_set_delay(ioc
, enabled
);
181 void qio_channel_set_cork(QIOChannel
*ioc
,
184 QIOChannelClass
*klass
= QIO_CHANNEL_GET_CLASS(ioc
);
186 if (klass
->io_set_cork
) {
187 klass
->io_set_cork(ioc
, enabled
);
192 off_t
qio_channel_io_seek(QIOChannel
*ioc
,
197 QIOChannelClass
*klass
= QIO_CHANNEL_GET_CLASS(ioc
);
199 if (!klass
->io_seek
) {
200 error_setg(errp
, "Channel does not support random access");
204 return klass
->io_seek(ioc
, offset
, whence
, errp
);
208 typedef struct QIOChannelYieldData QIOChannelYieldData
;
209 struct QIOChannelYieldData
{
215 static gboolean
qio_channel_yield_enter(QIOChannel
*ioc
,
216 GIOCondition condition
,
219 QIOChannelYieldData
*data
= opaque
;
220 qemu_coroutine_enter(data
->co
, NULL
);
225 void coroutine_fn
qio_channel_yield(QIOChannel
*ioc
,
226 GIOCondition condition
)
228 QIOChannelYieldData data
;
230 assert(qemu_in_coroutine());
232 data
.co
= qemu_coroutine_self();
233 qio_channel_add_watch(ioc
,
235 qio_channel_yield_enter
,
238 qemu_coroutine_yield();
242 static gboolean
qio_channel_wait_complete(QIOChannel
*ioc
,
243 GIOCondition condition
,
246 GMainLoop
*loop
= opaque
;
248 g_main_loop_quit(loop
);
253 void qio_channel_wait(QIOChannel
*ioc
,
254 GIOCondition condition
)
256 GMainContext
*ctxt
= g_main_context_new();
257 GMainLoop
*loop
= g_main_loop_new(ctxt
, TRUE
);
260 source
= qio_channel_create_watch(ioc
, condition
);
262 g_source_set_callback(source
,
263 (GSourceFunc
)qio_channel_wait_complete
,
267 g_source_attach(source
, ctxt
);
269 g_main_loop_run(loop
);
271 g_source_unref(source
);
272 g_main_loop_unref(loop
);
273 g_main_context_unref(ctxt
);
278 static void qio_channel_finalize(Object
*obj
)
280 QIOChannel
*ioc
= QIO_CHANNEL(obj
);
283 CloseHandle(ioc
->event
);
288 static const TypeInfo qio_channel_info
= {
289 .parent
= TYPE_OBJECT
,
290 .name
= TYPE_QIO_CHANNEL
,
291 .instance_size
= sizeof(QIOChannel
),
293 .instance_finalize
= qio_channel_finalize
,
296 .class_size
= sizeof(QIOChannelClass
),
300 static void qio_channel_register_types(void)
302 type_register_static(&qio_channel_info
);
306 type_init(qio_channel_register_types
);