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 "qapi/error.h"
24 #include "qemu/coroutine.h"
26 bool qio_channel_has_feature(QIOChannel
*ioc
,
27 QIOChannelFeature feature
)
29 return ioc
->features
& (1 << feature
);
33 ssize_t
qio_channel_readv_full(QIOChannel
*ioc
,
34 const struct iovec
*iov
,
40 QIOChannelClass
*klass
= QIO_CHANNEL_GET_CLASS(ioc
);
43 !(ioc
->features
& (1 << QIO_CHANNEL_FEATURE_FD_PASS
))) {
44 error_setg_errno(errp
, EINVAL
,
45 "Channel does not support file descriptor passing");
49 return klass
->io_readv(ioc
, iov
, niov
, fds
, nfds
, errp
);
53 ssize_t
qio_channel_writev_full(QIOChannel
*ioc
,
54 const struct iovec
*iov
,
60 QIOChannelClass
*klass
= QIO_CHANNEL_GET_CLASS(ioc
);
63 !(ioc
->features
& (1 << QIO_CHANNEL_FEATURE_FD_PASS
))) {
64 error_setg_errno(errp
, EINVAL
,
65 "Channel does not support file descriptor passing");
69 return klass
->io_writev(ioc
, iov
, niov
, fds
, nfds
, errp
);
73 ssize_t
qio_channel_readv(QIOChannel
*ioc
,
74 const struct iovec
*iov
,
78 return qio_channel_readv_full(ioc
, iov
, niov
, NULL
, NULL
, errp
);
82 ssize_t
qio_channel_writev(QIOChannel
*ioc
,
83 const struct iovec
*iov
,
87 return qio_channel_writev_full(ioc
, iov
, niov
, NULL
, 0, errp
);
91 ssize_t
qio_channel_read(QIOChannel
*ioc
,
96 struct iovec iov
= { .iov_base
= buf
, .iov_len
= buflen
};
97 return qio_channel_readv_full(ioc
, &iov
, 1, NULL
, NULL
, errp
);
101 ssize_t
qio_channel_write(QIOChannel
*ioc
,
106 struct iovec iov
= { .iov_base
= (char *)buf
, .iov_len
= buflen
};
107 return qio_channel_writev_full(ioc
, &iov
, 1, NULL
, 0, errp
);
111 int qio_channel_set_blocking(QIOChannel
*ioc
,
115 QIOChannelClass
*klass
= QIO_CHANNEL_GET_CLASS(ioc
);
116 return klass
->io_set_blocking(ioc
, enabled
, errp
);
120 int qio_channel_close(QIOChannel
*ioc
,
123 QIOChannelClass
*klass
= QIO_CHANNEL_GET_CLASS(ioc
);
124 return klass
->io_close(ioc
, errp
);
128 GSource
*qio_channel_create_watch(QIOChannel
*ioc
,
129 GIOCondition condition
)
131 QIOChannelClass
*klass
= QIO_CHANNEL_GET_CLASS(ioc
);
132 return klass
->io_create_watch(ioc
, condition
);
136 guint
qio_channel_add_watch(QIOChannel
*ioc
,
137 GIOCondition condition
,
140 GDestroyNotify notify
)
145 source
= qio_channel_create_watch(ioc
, condition
);
147 g_source_set_callback(source
, (GSourceFunc
)func
, user_data
, notify
);
149 id
= g_source_attach(source
, NULL
);
150 g_source_unref(source
);
156 int qio_channel_shutdown(QIOChannel
*ioc
,
157 QIOChannelShutdown how
,
160 QIOChannelClass
*klass
= QIO_CHANNEL_GET_CLASS(ioc
);
162 if (!klass
->io_shutdown
) {
163 error_setg(errp
, "Data path shutdown not supported");
167 return klass
->io_shutdown(ioc
, how
, errp
);
171 void qio_channel_set_delay(QIOChannel
*ioc
,
174 QIOChannelClass
*klass
= QIO_CHANNEL_GET_CLASS(ioc
);
176 if (klass
->io_set_delay
) {
177 klass
->io_set_delay(ioc
, enabled
);
182 void qio_channel_set_cork(QIOChannel
*ioc
,
185 QIOChannelClass
*klass
= QIO_CHANNEL_GET_CLASS(ioc
);
187 if (klass
->io_set_cork
) {
188 klass
->io_set_cork(ioc
, enabled
);
193 off_t
qio_channel_io_seek(QIOChannel
*ioc
,
198 QIOChannelClass
*klass
= QIO_CHANNEL_GET_CLASS(ioc
);
200 if (!klass
->io_seek
) {
201 error_setg(errp
, "Channel does not support random access");
205 return klass
->io_seek(ioc
, offset
, whence
, errp
);
209 typedef struct QIOChannelYieldData QIOChannelYieldData
;
210 struct QIOChannelYieldData
{
216 static gboolean
qio_channel_yield_enter(QIOChannel
*ioc
,
217 GIOCondition condition
,
220 QIOChannelYieldData
*data
= opaque
;
221 qemu_coroutine_enter(data
->co
, NULL
);
226 void coroutine_fn
qio_channel_yield(QIOChannel
*ioc
,
227 GIOCondition condition
)
229 QIOChannelYieldData data
;
231 assert(qemu_in_coroutine());
233 data
.co
= qemu_coroutine_self();
234 qio_channel_add_watch(ioc
,
236 qio_channel_yield_enter
,
239 qemu_coroutine_yield();
243 static gboolean
qio_channel_wait_complete(QIOChannel
*ioc
,
244 GIOCondition condition
,
247 GMainLoop
*loop
= opaque
;
249 g_main_loop_quit(loop
);
254 void qio_channel_wait(QIOChannel
*ioc
,
255 GIOCondition condition
)
257 GMainContext
*ctxt
= g_main_context_new();
258 GMainLoop
*loop
= g_main_loop_new(ctxt
, TRUE
);
261 source
= qio_channel_create_watch(ioc
, condition
);
263 g_source_set_callback(source
,
264 (GSourceFunc
)qio_channel_wait_complete
,
268 g_source_attach(source
, ctxt
);
270 g_main_loop_run(loop
);
272 g_source_unref(source
);
273 g_main_loop_unref(loop
);
274 g_main_context_unref(ctxt
);
279 static void qio_channel_finalize(Object
*obj
)
281 QIOChannel
*ioc
= QIO_CHANNEL(obj
);
284 CloseHandle(ioc
->event
);
289 static const TypeInfo qio_channel_info
= {
290 .parent
= TYPE_OBJECT
,
291 .name
= TYPE_QIO_CHANNEL
,
292 .instance_size
= sizeof(QIOChannel
),
294 .instance_finalize
= qio_channel_finalize
,
297 .class_size
= sizeof(QIOChannelClass
),
301 static void qio_channel_register_types(void)
303 type_register_static(&qio_channel_info
);
307 type_init(qio_channel_register_types
);