aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--autistdraw.c60
1 files changed, 33 insertions, 27 deletions
diff --git a/autistdraw.c b/autistdraw.c
index ce07540..8ca6dff 100644
--- a/autistdraw.c
+++ b/autistdraw.c
@@ -86,7 +86,8 @@ struct client
LIST_HEADER (client_t)
int fd; ///< Client connection
- ev_io watcher; ///< Client connection watcher
+ ev_io read_watcher; ///< Client readability watcher
+ ev_io write_watcher; ///< Client writability watcher
struct msg_reader msg_reader; ///< Client message reader
write_queue_t write_queue; ///< Write queue
};
@@ -106,7 +107,8 @@ struct app_context
// Client:
int server_fd; ///< Server connection
- ev_io server_watcher; ///< Server connection watcher
+ ev_io server_read_watcher; ///< Server readability watcher
+ ev_io server_write_watcher; ///< Server writability watcher
struct msg_reader msg_reader; ///< Server message reader
write_queue_t write_queue; ///< Server write queue
@@ -145,6 +147,8 @@ static void
app_init (app_context_t *self)
{
memset (self, 0, sizeof *self);
+ self->server_fd = -1;
+ self->listen_fd = -1;
msg_reader_init (&self->msg_reader);
write_queue_init (&self->write_queue);
}
@@ -193,7 +197,6 @@ flush_queue (write_queue_t *queue, ev_io *watcher)
for (write_req_t *iter = queue->head; iter; iter = iter->next)
*vec_iter++ = iter->data;
- int new_events = EV_READ;
ssize_t written;
again:
written = writev (watcher->fd, vec, N_ELEMENTS (vec));
@@ -209,12 +212,10 @@ again:
write_queue_processed (queue, written);
skip:
- if (!write_queue_is_empty (queue))
- new_events |= EV_WRITE;
-
- ev_io_stop (EV_DEFAULT_ watcher);
- ev_io_set (watcher, watcher->fd, new_events);
- ev_io_start (EV_DEFAULT_ watcher);
+ if (write_queue_is_empty (queue))
+ ev_io_stop (EV_DEFAULT_ watcher);
+ else
+ ev_io_start (EV_DEFAULT_ watcher);
return true;
}
@@ -230,18 +231,14 @@ static void
flush_writer_to_client (struct msg_writer *writer, client_t *client)
{
write_queue_add (&client->write_queue, flush_writer (writer));
- ev_io_stop (EV_DEFAULT_ &client->watcher);
- ev_io_set (&client->watcher, client->fd, EV_READ | EV_WRITE);
- ev_io_start (EV_DEFAULT_ &client->watcher);
+ ev_io_start (EV_DEFAULT_ &client->write_watcher);
}
static void
flush_writer_to_server (struct msg_writer *writer, app_context_t *app)
{
write_queue_add (&app->write_queue, flush_writer (writer));
- ev_io_stop (EV_DEFAULT_ &app->server_watcher);
- ev_io_set (&app->server_watcher, app->server_fd, EV_READ | EV_WRITE);
- ev_io_start (EV_DEFAULT_ &app->server_watcher);
+ ev_io_start (EV_DEFAULT_ &app->server_write_watcher);
}
static void
@@ -983,10 +980,13 @@ typedef bool (*server_handler_fn) (app_context_t *, struct msg_unpacker *);
static void
on_server_disconnected (app_context_t *app)
{
- // TODO: cancel any write requests?
- // XXX: should we unref it?
+ write_queue_free (&app->write_queue);
+ write_queue_init (&app->write_queue);
+
+ ev_io_stop (EV_DEFAULT_ &app->server_read_watcher);
+ ev_io_stop (EV_DEFAULT_ &app->server_write_watcher);
xclose (app->server_fd);
- ev_io_stop (EV_DEFAULT_ &app->server_watcher);
+ app->server_fd = -1;
display ("Disconnected!");
beep (); // Beep beep! Made a boo-boo.
@@ -1128,13 +1128,12 @@ typedef bool (*client_handler_fn)
static void
remove_client (app_context_t *app, client_t *client)
{
- // TODO: stop any watchers?
- // TODO: cancel any write requests?
- // XXX: should we unref it?
+ ev_io_stop (EV_DEFAULT_ &client->read_watcher);
+ ev_io_stop (EV_DEFAULT_ &client->write_watcher);
xclose (client->fd);
- LIST_UNLINK (app->clients, client);
msg_reader_free (&client->msg_reader);
write_queue_free (&client->write_queue);
+ LIST_UNLINK (app->clients, client);
free (client);
}
@@ -1269,9 +1268,13 @@ on_new_client (EV_P_ ev_io *watcher, int revents)
write_queue_init (&client->write_queue);
set_blocking (sock_fd, false);
- ev_io_init (&client->watcher, on_client_ready, sock_fd, EV_READ);
- client->watcher.data = client;
- ev_io_start (EV_A_ &client->watcher);
+ ev_io_init (&client->read_watcher, on_client_ready, sock_fd, EV_READ);
+ ev_io_init (&client->write_watcher, on_client_ready, sock_fd, EV_WRITE);
+ client->read_watcher.data = client;
+ client->write_watcher.data = client;
+
+ // We're only interested in reading as the write queue is empty now
+ ev_io_start (EV_A_ &client->read_watcher);
LIST_PREPEND (app->clients, client);
}
@@ -1460,8 +1463,11 @@ initialize_client (app_context_t *app, struct addrinfo *address)
set_blocking (sock_fd, false);
app->server_fd = sock_fd;
- ev_io_init (&app->server_watcher, on_server_ready, sock_fd, EV_READ);
- ev_io_start (EV_DEFAULT_ &app->server_watcher);
+ ev_io_init (&app->server_read_watcher, on_server_ready, sock_fd, EV_READ);
+ ev_io_init (&app->server_write_watcher, on_server_ready, sock_fd, EV_WRITE);
+
+ // We're only interested in reading as the write queue is empty now
+ ev_io_start (EV_DEFAULT_ &app->server_read_watcher);
send_hello_request (app);
send_get_bitmap_request (app);