From 51e1e7203fef0b729ccd115fa7f836ff22fd7d0c Mon Sep 17 00:00:00 2001 From: Marc Di Luzio Date: Tue, 24 Apr 2018 14:34:13 +0100 Subject: [PATCH] Add "reaper_freq" config setting in the "general" section This simply allows control over the reaper thread frequency. Defaults to 5 as before. --- README.md | 2 +- daemon/daemon_config.c | 37 +++++++++++++++++++++++++++++++++++++ daemon/daemon_config.h | 5 +++++ daemon/gamemode.c | 10 +++++----- data/gamemoded.1 | 4 ++++ 5 files changed, 52 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 8d57b2e..101f00f 100644 --- a/README.md +++ b/README.md @@ -78,7 +78,7 @@ Or, distribute `libgamemodeauto.so` and either add `-lgamemodeauto` to your link --- ## Configuration -The daemon can currently be configured using a `gamemode.ini` file in `/usr/share/gamemode/`. It will load the file when starting up. An example of what the file could look like is found in the `example` directory. +The daemon can currently be configured using a `gamemode.ini` file in `/usr/share/gamemode/`. It will load the file when starting up. An example of what the file could look like is found in the `example` directory and the man page contains details on entries. The file parsing uses [inih](https://github.com/benhoyt/inih). diff --git a/daemon/daemon_config.c b/daemon/daemon_config.c index b6a90f3..7b15dfa 100644 --- a/daemon/daemon_config.c +++ b/daemon/daemon_config.c @@ -51,6 +51,9 @@ POSSIBILITY OF SUCH DAMAGE. /* Maximum length of values in the whilelist or blacklist */ #define MAX_LIST_VALUE_LENGTH 256 +/* Default value for the reaper frequency */ +#define DEFAULT_REAPER_FREQ 5 + /** * The config holds various details as needed * and a rwlock to allow config_reload to be called @@ -62,6 +65,8 @@ struct GameModeConfig { char whitelist[MAX_LIST_VALUES][MAX_LIST_VALUE_LENGTH]; char blacklist[MAX_LIST_VALUES][MAX_LIST_VALUE_LENGTH]; + + long reaper_frequency; }; /* @@ -103,6 +108,21 @@ static int inih_handler(void *user, const char *section, const char *name, const MAX_LIST_VALUES); } } + } else if (strcmp(section, "general") == 0) { + if (strcmp(name, "reaper_freq") == 0) { + valid = true; + + char *end = NULL; + long chosen_freq = strtol(value, &end, 10); + + if (errno == ERANGE) { + LOG_MSG("reaper_freq value overflowed, given [%s]\n", value); + } else if (chosen_freq <= 0 || !(*value != '\0' && end && *end == '\0')) { + LOG_MSG("reaper_freq value was invalid, given [%s]\n", value); + } else { + self->reaper_frequency = chosen_freq; + } + } } if (!valid) { @@ -124,6 +144,7 @@ static void load_config_file(GameModeConfig *self) /* Clear our config values */ memset(self->whitelist, 0, sizeof(self->whitelist)); memset(self->blacklist, 0, sizeof(self->blacklist)); + self->reaper_frequency = DEFAULT_REAPER_FREQ; /* try locally first */ FILE *f = fopen(CONFIG_NAME, "r"); @@ -243,3 +264,19 @@ bool config_get_client_blacklisted(GameModeConfig *self, const char *client) pthread_rwlock_unlock(&self->rwlock); return found; } + +/* + * Gets the reaper frequency + */ +long config_get_reaper_thread_frequency(GameModeConfig *self) +{ + long value; + /* Take the read lock */ + pthread_rwlock_rdlock(&self->rwlock); + + value = self->reaper_frequency; + + /* release the lock */ + pthread_rwlock_unlock(&self->rwlock); + return value; +} diff --git a/daemon/daemon_config.h b/daemon/daemon_config.h index c7e0870..a18dd15 100644 --- a/daemon/daemon_config.h +++ b/daemon/daemon_config.h @@ -70,3 +70,8 @@ bool config_get_client_whitelisted(GameModeConfig *self, const char *client); * Get if the client is in the blacklist */ bool config_get_client_blacklisted(GameModeConfig *self, const char *client); + +/* + * Get the frequency (in seconds) for the reaper thread + */ +long config_get_reaper_thread_frequency(GameModeConfig *self); diff --git a/daemon/gamemode.c b/daemon/gamemode.c index 3752b40..0d90553 100644 --- a/daemon/gamemode.c +++ b/daemon/gamemode.c @@ -76,9 +76,6 @@ static GameModeContext instance = { 0 }; /* Maximum number of concurrent processes we'll sanely support */ #define MAX_GAMES 256 -/* How often our reaper thread will run */ -#define SLEEP_INTERVAL 5 - /** * Protect against signals */ @@ -384,8 +381,11 @@ static void *game_mode_context_reaper(void *userdata) { /* Stack, not allocated, won't disappear. */ GameModeContext *self = userdata; + + long reaper_interval = config_get_reaper_thread_frequency(self->config); + struct timespec ts = { 0, 0 }; - ts.tv_sec = time(NULL) + SLEEP_INTERVAL; + ts.tv_sec = time(NULL) + reaper_interval; while (self->reaper.running) { /* Wait for condition */ @@ -401,7 +401,7 @@ static void *game_mode_context_reaper(void *userdata) /* Expire remaining entries */ game_mode_context_auto_expire(self); - ts.tv_sec = time(NULL) + SLEEP_INTERVAL; + ts.tv_sec = time(NULL) + reaper_interval; } return NULL; diff --git a/data/gamemoded.1 b/data/gamemoded.1 index 6e39250..e5c90af 100644 --- a/data/gamemoded.1 +++ b/data/gamemoded.1 @@ -74,6 +74,10 @@ Behaviour of the config file can be explained by presenting a commented example: .RS 4 .nf +[general] +; The reaper thread will check every 10 seconds for exited clients +reaper_freq=10 + [filter] ; If "whitelist" entry has a value(s) ; gamemode will reject anything not in the whitelist