diff options
author | Max Kellermann <max@duempel.org> | 2013-01-16 21:39:40 +0100 |
---|---|---|
committer | Max Kellermann <max@duempel.org> | 2013-01-16 21:51:08 +0100 |
commit | b0bbb8b693d846c2710ec84bfa79dcaa3a21729a (patch) | |
tree | 43cba39160446e9379c188ebb23eae5633de4ea7 /src | |
parent | cab84af72e373acca0e88d9b407aa97796c083e0 (diff) | |
download | mpd-b0bbb8b693d846c2710ec84bfa79dcaa3a21729a.tar.gz mpd-b0bbb8b693d846c2710ec84bfa79dcaa3a21729a.tar.xz mpd-b0bbb8b693d846c2710ec84bfa79dcaa3a21729a.zip |
Client: use TimeoutMonitor to track connection timeout
Don't use a global loop over the whole client list.
Diffstat (limited to 'src')
-rw-r--r-- | src/ClientExpire.cxx | 53 | ||||
-rw-r--r-- | src/ClientGlobal.cxx | 2 | ||||
-rw-r--r-- | src/ClientIdle.cxx | 8 | ||||
-rw-r--r-- | src/ClientInternal.hxx | 25 | ||||
-rw-r--r-- | src/ClientNew.cxx | 8 | ||||
-rw-r--r-- | src/ClientRead.cxx | 4 |
6 files changed, 22 insertions, 78 deletions
diff --git a/src/ClientExpire.cxx b/src/ClientExpire.cxx index 56b003df8..8f57f5b3e 100644 --- a/src/ClientExpire.cxx +++ b/src/ClientExpire.cxx @@ -19,9 +19,6 @@ #include "config.h" #include "ClientInternal.hxx" -#include "ClientList.hxx" - -static guint expire_source_id; void Client::SetExpired() @@ -29,54 +26,18 @@ Client::SetExpired() if (IsExpired()) return; - client_schedule_expire(); BufferedSocket::Close(); + TimeoutMonitor::Schedule(0); } -static void -client_check_expired_callback(Client *client, G_GNUC_UNUSED gpointer user_data) +bool +Client::OnTimeout() { - if (client->IsExpired()) { - g_debug("[%u] expired", client->num); - client->Close(); - } else if (!client->idle_waiting && /* idle clients - never expire */ - (int)g_timer_elapsed(client->last_activity, NULL) > - client_timeout) { - g_debug("[%u] timeout", client->num); - client->Close(); + if (!IsExpired()) { + assert(!idle_waiting); + g_debug("[%u] timeout", num); } -} - -static void -client_manager_expire(void) -{ - client_list_foreach(client_check_expired_callback, NULL); -} -/** - * An idle event which calls client_manager_expire(). - */ -static gboolean -client_manager_expire_event(G_GNUC_UNUSED gpointer data) -{ - expire_source_id = 0; - client_manager_expire(); + Close(); return false; } - -void -client_schedule_expire(void) -{ - if (expire_source_id == 0) - /* delayed deletion */ - expire_source_id = g_idle_add(client_manager_expire_event, - NULL); -} - -void -client_deinit_expire(void) -{ - if (expire_source_id != 0) - g_source_remove(expire_source_id); -} diff --git a/src/ClientGlobal.cxx b/src/ClientGlobal.cxx index 1aa82b435..47179b53d 100644 --- a/src/ClientGlobal.cxx +++ b/src/ClientGlobal.cxx @@ -69,6 +69,4 @@ void client_manager_deinit(void) client_close_all(); client_max_connections = 0; - - client_deinit_expire(); } diff --git a/src/ClientIdle.cxx b/src/ClientIdle.cxx index b440a8260..89cb10aa1 100644 --- a/src/ClientIdle.cxx +++ b/src/ClientIdle.cxx @@ -43,7 +43,8 @@ Client::IdleNotify() } client_puts(this, "OK\n"); - g_timer_start(last_activity); + + TimeoutMonitor::ScheduleSeconds(client_timeout); } void @@ -83,6 +84,9 @@ Client::IdleWait(unsigned flags) if (idle_flags & idle_subscriptions) { IdleNotify(); return true; - } else + } else { + /* disable timeouts while in "idle" */ + TimeoutMonitor::Cancel(); return false; + } } diff --git a/src/ClientInternal.hxx b/src/ClientInternal.hxx index 9384b84ee..097029f0b 100644 --- a/src/ClientInternal.hxx +++ b/src/ClientInternal.hxx @@ -25,6 +25,7 @@ #include "ClientMessage.hxx" #include "CommandListBuilder.hxx" #include "event/BufferedSocket.hxx" +#include "event/TimeoutMonitor.hxx" #include "command.h" #include <set> @@ -43,7 +44,7 @@ enum { struct Partition; -class Client final : private BufferedSocket { +class Client final : private BufferedSocket, TimeoutMonitor { public: Partition &partition; struct playlist &playlist; @@ -54,11 +55,6 @@ public: /** the uid of the client process, or -1 if unknown */ int uid; - /** - * How long since the last activity from this client? - */ - GTimer *last_activity; - CommandListBuilder cmd_list; unsigned int num; /* client number */ @@ -91,7 +87,6 @@ public: Client(EventLoop &loop, Partition &partition, int fd, int uid, int num); - ~Client(); bool IsConnected() const { return BufferedSocket::IsDefined(); @@ -125,6 +120,9 @@ private: size_t length) override; virtual void OnSocketError(GError *error) override; virtual void OnSocketClosed() override; + + /* virtual methods from class TimeoutMonitor */ + virtual bool OnTimeout() override; }; extern unsigned int client_max_connections; @@ -132,19 +130,6 @@ extern int client_timeout; extern size_t client_max_command_list_size; extern size_t client_max_output_buffer_size; -/** - * Schedule an "expired" check for all clients: permanently delete - * clients which have been set "expired" with client_set_expired(). - */ -void -client_schedule_expire(void); - -/** - * Removes a scheduled "expired" check. - */ -void -client_deinit_expire(void); - enum command_return client_read(Client *client); diff --git a/src/ClientNew.cxx b/src/ClientNew.cxx index 42cc3470d..2a4774c55 100644 --- a/src/ClientNew.cxx +++ b/src/ClientNew.cxx @@ -49,20 +49,16 @@ static const char GREETING[] = "OK MPD " PROTOCOL_VERSION "\n"; Client::Client(EventLoop &_loop, Partition &_partition, int _fd, int _uid, int _num) :BufferedSocket(_fd, _loop, 16384, client_max_output_buffer_size), + TimeoutMonitor(_loop), partition(_partition), playlist(partition.playlist), player_control(&partition.pc), permission(getDefaultPermissions()), uid(_uid), - last_activity(g_timer_new()), num(_num), idle_waiting(false), idle_flags(0), num_subscriptions(0) { -} - -Client::~Client() -{ - g_timer_destroy(last_activity); + TimeoutMonitor::ScheduleSeconds(client_timeout); } void diff --git a/src/ClientRead.cxx b/src/ClientRead.cxx index 363363d1f..49c698bc1 100644 --- a/src/ClientRead.cxx +++ b/src/ClientRead.cxx @@ -28,13 +28,13 @@ BufferedSocket::InputResult Client::OnSocketInput(const void *data, size_t length) { - g_timer_start(last_activity); - const char *p = (const char *)data; const char *newline = (const char *)memchr(p, '\n', length); if (newline == NULL) return InputResult::MORE; + TimeoutMonitor::ScheduleSeconds(client_timeout); + char *line = g_strndup(p, newline - p); BufferedSocket::ConsumeInput(newline + 1 - p); |