aboutsummaryrefslogtreecommitdiff
path: root/src/kike.c
diff options
context:
space:
mode:
authorPřemysl Janouch <p.janouch@gmail.com>2014-08-02 20:50:33 +0200
committerPřemysl Janouch <p.janouch@gmail.com>2014-08-02 21:33:55 +0200
commit559bedad650796967f928e1d0b7fbdcf74a03f27 (patch)
treef5ec1dd11ed8a66da913333b6256e57e3fdaffc4 /src/kike.c
parent5e6def5bb0b2f4f43116d907c764d8e3527fe770 (diff)
downloadxK-559bedad650796967f928e1d0b7fbdcf74a03f27.tar.gz
xK-559bedad650796967f928e1d0b7fbdcf74a03f27.tar.xz
xK-559bedad650796967f928e1d0b7fbdcf74a03f27.zip
kike: update the poller properly
Now we can send PRIVMSG's between users and all that jazz.
Diffstat (limited to 'src/kike.c')
-rw-r--r--src/kike.c43
1 files changed, 24 insertions, 19 deletions
diff --git a/src/kike.c b/src/kike.c
index bc64180..73b6df1 100644
--- a/src/kike.c
+++ b/src/kike.c
@@ -446,6 +446,7 @@ server_context_free (struct server_context *self)
static void client_cancel_timers (struct client *);
static void client_set_kill_timer (struct client *);
+static void client_update_poller (struct client *, const struct pollfd *);
static void
client_unregister (struct client *c, const char *reason)
@@ -497,10 +498,12 @@ static void
irc_send_str (struct client *c, const struct str *s)
{
// TODO: kill the connection above some "SendQ" threshold (careful!)
-
str_append_data (&c->write_buffer, s->str,
s->len > IRC_MAX_MESSAGE_LENGTH ? IRC_MAX_MESSAGE_LENGTH : s->len);
str_append (&c->write_buffer, "\r\n");
+ // XXX: we might want to move this elsewhere, so that it doesn't get called
+ // as often; it's going to cause a lot of syscalls with epoll.
+ client_update_poller (c, NULL);
}
static void irc_send (struct client *c,
@@ -1243,15 +1246,29 @@ on_irc_client_ready (const struct pollfd *pfd, void *user_data)
client_set_ping_timer (c);
}
- int new_events = 0;
if (c->ssl)
{
// Reads may want to write, writes may want to read, poll() may
// return unexpected things in `revents'... let's try both
if (!irc_try_read_ssl (c) || !irc_try_write_ssl (c))
return;
+ }
+ else if (!irc_try_read (c) || !irc_try_write (c))
+ return;
+
+ client_update_poller (c, pfd);
+
+ // The purpose of the `closing_link' state is to transfer the `ERROR'
+ if (c->closing_link && !c->write_buffer.len)
+ client_kill (c, NULL);
+}
- new_events |= POLLIN;
+static void
+client_update_poller (struct client *c, const struct pollfd *pfd)
+{
+ int new_events = POLLIN;
+ if (c->ssl)
+ {
if (c->write_buffer.len || c->ssl_rx_want_tx)
new_events |= POLLOUT;
@@ -1259,24 +1276,13 @@ on_irc_client_ready (const struct pollfd *pfd, void *user_data)
if (c->ssl_rx_want_tx) new_events &= ~POLLIN;
if (c->ssl_tx_want_rx) new_events &= ~POLLOUT;
}
- else
- {
- if (!irc_try_read (c) || !irc_try_write (c))
- return;
-
- new_events |= POLLIN;
- if (c->write_buffer.len)
- new_events |= POLLOUT;
- }
+ else if (c->write_buffer.len)
+ new_events |= POLLOUT;
hard_assert (new_events != 0);
- if (pfd->events != new_events)
+ if (!pfd || pfd->events != new_events)
poller_set (&c->ctx->poller, c->socket_fd, new_events,
(poller_dispatcher_func) on_irc_client_ready, c);
-
- // The purpose of the `closing_link' state is to transfer the `ERROR'
- if (c->closing_link && !c->write_buffer.len)
- client_kill (c, NULL);
}
static void
@@ -1329,8 +1335,7 @@ on_irc_client_available (const struct pollfd *pfd, void *user_data)
ctx->n_clients++;
set_blocking (fd, false);
- poller_set (&ctx->poller, fd, POLLIN,
- (poller_dispatcher_func) on_irc_client_ready, c);
+ client_update_poller (c, NULL);
client_set_kill_timer (c);
}
}