kike: update the poller properly

Now we can send PRIVMSG's between users and all that jazz.
This commit is contained in:
Přemysl Eric Janouch 2014-08-02 20:50:33 +02:00
parent 5e6def5bb0
commit 559bedad65

View File

@ -446,6 +446,7 @@ server_context_free (struct server_context *self)
static void client_cancel_timers (struct client *); static void client_cancel_timers (struct client *);
static void client_set_kill_timer (struct client *); static void client_set_kill_timer (struct client *);
static void client_update_poller (struct client *, const struct pollfd *);
static void static void
client_unregister (struct client *c, const char *reason) client_unregister (struct client *c, const char *reason)
@ -497,10 +498,12 @@ static void
irc_send_str (struct client *c, const struct str *s) irc_send_str (struct client *c, const struct str *s)
{ {
// TODO: kill the connection above some "SendQ" threshold (careful!) // TODO: kill the connection above some "SendQ" threshold (careful!)
str_append_data (&c->write_buffer, s->str, str_append_data (&c->write_buffer, s->str,
s->len > IRC_MAX_MESSAGE_LENGTH ? IRC_MAX_MESSAGE_LENGTH : s->len); s->len > IRC_MAX_MESSAGE_LENGTH ? IRC_MAX_MESSAGE_LENGTH : s->len);
str_append (&c->write_buffer, "\r\n"); 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, 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); client_set_ping_timer (c);
} }
int new_events = 0;
if (c->ssl) if (c->ssl)
{ {
// Reads may want to write, writes may want to read, poll() may // Reads may want to write, writes may want to read, poll() may
// return unexpected things in `revents'... let's try both // return unexpected things in `revents'... let's try both
if (!irc_try_read_ssl (c) || !irc_try_write_ssl (c)) if (!irc_try_read_ssl (c) || !irc_try_write_ssl (c))
return; return;
}
else if (!irc_try_read (c) || !irc_try_write (c))
return;
new_events |= POLLIN; 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);
}
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) if (c->write_buffer.len || c->ssl_rx_want_tx)
new_events |= POLLOUT; 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_rx_want_tx) new_events &= ~POLLIN;
if (c->ssl_tx_want_rx) new_events &= ~POLLOUT; if (c->ssl_tx_want_rx) new_events &= ~POLLOUT;
} }
else else if (c->write_buffer.len)
{ new_events |= POLLOUT;
if (!irc_try_read (c) || !irc_try_write (c))
return;
new_events |= POLLIN;
if (c->write_buffer.len)
new_events |= POLLOUT;
}
hard_assert (new_events != 0); 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_set (&c->ctx->poller, c->socket_fd, new_events,
(poller_dispatcher_func) on_irc_client_ready, c); (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 static void
@ -1329,8 +1335,7 @@ on_irc_client_available (const struct pollfd *pfd, void *user_data)
ctx->n_clients++; ctx->n_clients++;
set_blocking (fd, false); set_blocking (fd, false);
poller_set (&ctx->poller, fd, POLLIN, client_update_poller (c, NULL);
(poller_dispatcher_func) on_irc_client_ready, c);
client_set_kill_timer (c); client_set_kill_timer (c);
} }
} }