diff options
author | Russell King <rmk@armlinux.org.uk> | 2021-09-11 13:57:42 +0100 |
---|---|---|
committer | Russell King <rmk@armlinux.org.uk> | 2021-09-11 13:57:42 +0100 |
commit | 2f45bcf78b77193ad6107fbb92ad0f93eb1ad4fc (patch) | |
tree | 18b115356a92e67e2276a2dbe97139d2237c0f24 /resource.c | |
parent | acc52e700121120726b42a6dadd8c12f030ba349 (diff) |
Restrict updates to the newest updater
Prevent old update connections from providing updates, closing them if
they attempt an update.
In doing so, this also limits resource usage when we have multiple
updaters connected (which should never happen.)
Signed-off-by: Russell King <rmk@armlinux.org.uk>
Diffstat (limited to 'resource.c')
-rw-r--r-- | resource.c | 34 |
1 files changed, 28 insertions, 6 deletions
@@ -73,6 +73,20 @@ static int object_v1_get(struct client *c, struct resource *r) return 1; } +static void object_v1_close(struct client *c, struct resource *r) +{ + struct resource_object *obj = r->data; + + // Remove this client from the object list + resource_obj_del_client(obj, c); +} + +static void object_v1_update_open(struct client *c, struct resource *r) +{ + // Keep track of the latest updater + r->updater = c; +} + // Update all attached clients with the new resource object data static int object_v1_update(struct client *c, struct resource *r, const char *m) { @@ -80,6 +94,12 @@ static int object_v1_update(struct client *c, struct resource *r, const char *m) GString *string; char *n; + // Only allow the latest updater to provide updates, in case we + // end up with multiple connections. This also allows us to quickly + // release the resources of a stale connection. + if (r->updater != c) + return -1; + // Remove any trailing whitespace. n = g_strchomp(g_strdup(m)); @@ -97,18 +117,20 @@ static int object_v1_update(struct client *c, struct resource *r, const char *m) return 0; } -static void object_v1_close(struct client *c, struct resource *r) +static void object_v1_update_close(struct client *c, struct resource *r) { - struct resource_object *obj = r->data; - - // Remove this client from the object list - resource_obj_del_client(obj, c); + // If the updater goes away, clear the data so we don't serve + // stale data. + if (r->updater == c) + r->updater = NULL; } static const struct resource_ops resource_v1_ops = { .get = object_v1_get, - .update = object_v1_update, .close = object_v1_close, + .update_open = object_v1_update_open, + .update = object_v1_update, + .update_close = object_v1_update_close, }; static struct resource resource_position1 = { |