return ret;
}
- qio_channel_set_blocking(s->ioc, false, NULL);
+ if (!qio_channel_set_blocking(s->ioc, false, errp)) {
+ return -EINVAL;
+ }
qio_channel_set_follow_coroutine_ctx(s->ioc, true);
/* successfully connected */
SocketChardev *s = SOCKET_CHARDEV(chr);
int size;
int saved_errno;
+ Error *local_err = NULL;
if (s->state != TCP_CHARDEV_STATE_CONNECTED) {
return 0;
}
- qio_channel_set_blocking(s->ioc, true, NULL);
+ if (!qio_channel_set_blocking(s->ioc, true, &local_err)) {
+ error_report_err(local_err);
+ return -1;
+ }
size = tcp_chr_recv(chr, (void *) buf, len);
saved_errno = errno;
if (s->state != TCP_CHARDEV_STATE_DISCONNECTED) {
- qio_channel_set_blocking(s->ioc, false, NULL);
+ if (!qio_channel_set_blocking(s->ioc, false, &local_err)) {
+ error_report_err(local_err);
+ /* failed to recover non-blocking state */
+ tcp_chr_disconnect(chr);
+ }
}
if (size == 0) {
/* connection closed */
static int tcp_chr_new_client(Chardev *chr, QIOChannelSocket *sioc)
{
SocketChardev *s = SOCKET_CHARDEV(chr);
+ Error *local_err = NULL;
if (s->state != TCP_CHARDEV_STATE_CONNECTING) {
return -1;
}
+ if (!qio_channel_set_blocking(QIO_CHANNEL(sioc), false, &local_err)) {
+ error_report_err(local_err);
+ return -1;
+ }
+
s->ioc = QIO_CHANNEL(sioc);
object_ref(OBJECT(sioc));
s->sioc = sioc;
object_ref(OBJECT(sioc));
- qio_channel_set_blocking(s->ioc, false, NULL);
-
if (s->do_nodelay) {
qio_channel_set_delay(s->ioc, false);
}
return;
}
+ if (!qio_channel_set_blocking(dev->ioc, true, errp)) {
+ object_unref(dev->ioc);
+ return;
+ }
+
qemu_mutex_init(&dev->io_mutex);
- qio_channel_set_blocking(dev->ioc, true, NULL);
pci_conf[PCI_LATENCY_TIMER] = 0xff;
pci_conf[PCI_INTERRUPT_PIN] = 0x01;
error_report_err(err);
return;
}
- qio_channel_set_blocking(ioc, false, NULL);
+ if (!qio_channel_set_blocking(ioc, false, &err)) {
+ error_report_err(err);
+ object_unref(OBJECT(ioc));
+ return;
+ }
o->dev = dev;
sioc = qio_channel_socket_new();
ioc = QIO_CHANNEL(sioc);
if (qio_channel_socket_connect_sync(sioc, addr, errp) < 0) {
- object_unref(OBJECT(ioc));
- return NULL;
+ goto fail;
+ }
+ if (!qio_channel_set_blocking(ioc, false, errp)) {
+ goto fail;
}
- qio_channel_set_blocking(ioc, false, NULL);
proxy = g_malloc0(sizeof(VFIOUserProxy));
proxy->sockname = g_strdup_printf("unix:%s", sockname);
QLIST_INSERT_HEAD(&vfio_user_sockets, proxy, next);
return proxy;
+
+fail:
+ object_unref(OBJECT(ioc));
+ return NULL;
}
void vfio_user_set_handler(VFIODevice *vbasedev,
* return QIO_CHANNEL_ERR_BLOCK if they would otherwise
* block on I/O
*/
-int qio_channel_set_blocking(QIOChannel *ioc,
- bool enabled,
- Error **errp);
+bool qio_channel_set_blocking(QIOChannel *ioc,
+ bool enabled,
+ Error **errp);
/**
* qio_channel_set_follow_coroutine_ctx:
{
QIOChannelTLS *tioc = QIO_CHANNEL_TLS(ioc);
- return qio_channel_set_blocking(tioc->master, enabled, errp);
+ return qio_channel_set_blocking(tioc->master, enabled, errp) ? 0 : -1;
}
static void qio_channel_tls_set_delay(QIOChannel *ioc,
{
QIOChannelWebsock *wioc = QIO_CHANNEL_WEBSOCK(ioc);
- qio_channel_set_blocking(wioc->master, enabled, errp);
- return 0;
+ return qio_channel_set_blocking(wioc->master, enabled, errp) ? 0 : -1;
}
static void qio_channel_websock_set_delay(QIOChannel *ioc,
}
-int qio_channel_set_blocking(QIOChannel *ioc,
+bool qio_channel_set_blocking(QIOChannel *ioc,
bool enabled,
Error **errp)
{
QIOChannelClass *klass = QIO_CHANNEL_GET_CLASS(ioc);
- return klass->io_set_blocking(ioc, enabled, errp);
+ return klass->io_set_blocking(ioc, enabled, errp) == 0;
}
....options sent, ending in NBD_OPT_EXPORT_NAME or NBD_OPT_GO....
*/
- qio_channel_set_blocking(client->ioc, false, NULL);
+ if (!qio_channel_set_blocking(client->ioc, false, errp)) {
+ return -EINVAL;
+ }
qio_channel_set_follow_coroutine_ctx(client->ioc, true);
trace_nbd_negotiate_begin();
uint32_t flags;
int r;
- qio_channel_set_blocking(QIO_CHANNEL(client->ioc),
- false, NULL);
+ if (!qio_channel_set_blocking(QIO_CHANNEL(client->ioc),
+ false, &local_err)) {
+ goto out;
+ }
+
qio_channel_set_follow_coroutine_ctx(QIO_CHANNEL(client->ioc), true);
/* A very simple negotiation for future extensibility. No features
}
}
+out:
if (local_err) {
if (verbose == 0) {
error_free(local_err);
}
}
-out:
object_unref(OBJECT(client->ioc));
g_free(client);
}
#include "qemu/osdep.h"
#include "io-channel-helpers.h"
+#include "qapi/error.h"
#include "qemu/iov.h"
struct QIOChannelTest {
test->src = src;
test->dst = dst;
- qio_channel_set_blocking(test->dst, blocking, NULL);
- qio_channel_set_blocking(test->src, blocking, NULL);
+ qio_channel_set_blocking(test->dst, blocking, &error_abort);
+ qio_channel_set_blocking(test->src, blocking, &error_abort);
reader = g_thread_new("reader",
test_io_thread_reader,
* thread, so we need these non-blocking to avoid deadlock
* of ourselves
*/
- qio_channel_set_blocking(QIO_CHANNEL(clientChanSock), false, NULL);
- qio_channel_set_blocking(QIO_CHANNEL(serverChanSock), false, NULL);
+ qio_channel_set_blocking(QIO_CHANNEL(clientChanSock), false, &error_abort);
+ qio_channel_set_blocking(QIO_CHANNEL(serverChanSock), false, &error_abort);
/* Now the real part of the test, setup the sessions */
clientChanTLS = qio_channel_tls_new_client(
uint64_t vmsr;
int r;
- qio_channel_set_blocking(QIO_CHANNEL(client->ioc),
- false, NULL);
+ if (!qio_channel_set_blocking(QIO_CHANNEL(client->ioc),
+ false, &local_err)) {
+ goto out;
+ }
qio_channel_set_follow_coroutine_ctx(QIO_CHANNEL(client->ioc), true);
VNC_DEBUG("New client on socket %p\n", vs->sioc);
update_displaychangelistener(&vd->dcl, VNC_REFRESH_INTERVAL_BASE);
- qio_channel_set_blocking(vs->ioc, false, NULL);
+ qio_channel_set_blocking(vs->ioc, false, &error_abort);
if (vs->ioc_tag) {
g_source_remove(vs->ioc_tag);
}
gpointer opaque)
{
VuServer *server = opaque;
+ Error *local_err = NULL;
if (server->sioc) {
warn_report("Only one vhost-user client is allowed to "
object_ref(OBJECT(server->ioc));
/* TODO vu_message_write() spins if non-blocking! */
- qio_channel_set_blocking(server->ioc, false, NULL);
+ if (!qio_channel_set_blocking(server->ioc, false, &local_err)) {
+ error_report_err(local_err);
+ vu_deinit(&server->vu_dev);
+ return;
+ }
qio_channel_set_follow_coroutine_ctx(server->ioc, true);