#include "qemu/osdep.h"
#include "qapi/error.h"
+#include "qapi/qapi-visit-sockets.h"
#include "io/channel-socket.h"
#include "io/channel-watch.h"
#include "trace.h"
int fd;
trace_qio_channel_socket_connect_sync(ioc, addr);
- fd = socket_connect(addr, errp, NULL, NULL);
+ fd = socket_connect(addr, errp);
if (fd < 0) {
trace_qio_channel_socket_connect_fail(ioc);
return -1;
SocketAddress *addr,
QIOTaskFunc callback,
gpointer opaque,
- GDestroyNotify destroy)
+ GDestroyNotify destroy,
+ GMainContext *context)
{
QIOTask *task = qio_task_new(
OBJECT(ioc), callback, opaque, destroy);
qio_task_run_in_thread(task,
qio_channel_socket_connect_worker,
addrCopy,
- (GDestroyNotify)qapi_free_SocketAddress);
+ (GDestroyNotify)qapi_free_SocketAddress,
+ context);
}
SocketAddress *addr,
QIOTaskFunc callback,
gpointer opaque,
- GDestroyNotify destroy)
+ GDestroyNotify destroy,
+ GMainContext *context)
{
QIOTask *task = qio_task_new(
OBJECT(ioc), callback, opaque, destroy);
qio_task_run_in_thread(task,
qio_channel_socket_listen_worker,
addrCopy,
- (GDestroyNotify)qapi_free_SocketAddress);
+ (GDestroyNotify)qapi_free_SocketAddress,
+ context);
}
SocketAddress *remoteAddr,
QIOTaskFunc callback,
gpointer opaque,
- GDestroyNotify destroy)
+ GDestroyNotify destroy,
+ GMainContext *context)
{
QIOTask *task = qio_task_new(
OBJECT(ioc), callback, opaque, destroy);
qio_task_run_in_thread(task,
qio_channel_socket_dgram_worker,
data,
- qio_channel_socket_dgram_worker_free);
+ qio_channel_socket_dgram_worker_free,
+ context);
}
{
QIOChannelSocket *cioc;
- cioc = QIO_CHANNEL_SOCKET(object_new(TYPE_QIO_CHANNEL_SOCKET));
- cioc->fd = -1;
+ cioc = qio_channel_socket_new();
cioc->remoteAddrLen = sizeof(ioc->remoteAddr);
cioc->localAddrLen = sizeof(ioc->localAddr);
-#ifdef WIN32
- QIO_CHANNEL(cioc)->event = CreateEvent(NULL, FALSE, FALSE, NULL);
-#endif
-
-
retry:
trace_qio_channel_socket_accept(ioc);
cioc->fd = qemu_accept(ioc->fd, (struct sockaddr *)&cioc->remoteAddr,
&cioc->remoteAddrLen);
if (cioc->fd < 0) {
- trace_qio_channel_socket_accept_fail(ioc);
if (errno == EINTR) {
goto retry;
}
+ error_setg_errno(errp, errno, "Unable to accept connection");
+ trace_qio_channel_socket_accept_fail(ioc);
goto error;
}
qemu_set_block(sioc->fd);
} else {
qemu_set_nonblock(sioc->fd);
-#ifdef WIN32
- WSAEventSelect(sioc->fd, ioc->event,
- FD_READ | FD_ACCEPT | FD_CLOSE |
- FD_CONNECT | FD_WRITE | FD_OOB);
-#endif
}
return 0;
}
Error **errp)
{
QIOChannelSocket *sioc = QIO_CHANNEL_SOCKET(ioc);
+ int rc = 0;
if (sioc->fd != -1) {
#ifdef WIN32
WSAEventSelect(sioc->fd, NULL, 0);
#endif
+ if (qio_channel_has_feature(ioc, QIO_CHANNEL_FEATURE_LISTEN)) {
+ socket_listen_cleanup(sioc->fd, errp);
+ }
+
if (closesocket(sioc->fd) < 0) {
sioc->fd = -1;
error_setg_errno(errp, errno,
}
sioc->fd = -1;
}
- return 0;
+ return rc;
}
static int
return 0;
}
+static void qio_channel_socket_set_aio_fd_handler(QIOChannel *ioc,
+ AioContext *ctx,
+ IOHandler *io_read,
+ IOHandler *io_write,
+ void *opaque)
+{
+ QIOChannelSocket *sioc = QIO_CHANNEL_SOCKET(ioc);
+ aio_set_fd_handler(ctx, sioc->fd, false, io_read, io_write, NULL, opaque);
+}
+
static GSource *qio_channel_socket_create_watch(QIOChannel *ioc,
GIOCondition condition)
{
ioc_klass->io_set_cork = qio_channel_socket_set_cork;
ioc_klass->io_set_delay = qio_channel_socket_set_delay;
ioc_klass->io_create_watch = qio_channel_socket_create_watch;
+ ioc_klass->io_set_aio_fd_handler = qio_channel_socket_set_aio_fd_handler;
}
static const TypeInfo qio_channel_socket_info = {