Skip to content

Commit

Permalink
clipctl: Use exponential backoff for clipmenud state change detection
Browse files Browse the repository at this point in the history
This was previously hardcoded to 100ms, which is way too high.

Fixes #234.
  • Loading branch information
cdown committed Nov 9, 2024
1 parent 1113ca8 commit 30fa2c3
Showing 1 changed file with 21 additions and 2 deletions.
23 changes: 21 additions & 2 deletions src/clipctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <time.h>
#include <unistd.h>

#include "config.h"
Expand Down Expand Up @@ -68,7 +69,6 @@ static bool _nonnull_ should_enable(struct config *cfg, const char *mode_str) {

/* The number of times to check if state was updated before giving up */
#define MAX_STATE_RETRIES 20
#define USEC_IN_MS 1000

int main(int argc, char *argv[]) {
_drop_(config_free) struct config cfg = setup("clipctl");
Expand All @@ -89,11 +89,30 @@ int main(int argc, char *argv[]) {
expect(kill(pid, want_enable ? SIGUSR2 : SIGUSR1) == 0);
dbg("Sent signal to pid %d\n", pid);

unsigned int delay_ms = 1;
unsigned int total_wait_ms = 0;
const unsigned int max_wait_ms = 1000;

for (size_t retries = 0; retries < MAX_STATE_RETRIES; ++retries) {
if (is_enabled(&cfg) == want_enable) {
return 0;
}
usleep(100 * USEC_IN_MS);

if (total_wait_ms >= max_wait_ms) {
break;
}

struct timespec req = {.tv_sec = delay_ms / 1000,
.tv_nsec = (delay_ms % 1000) * 1000000L};
struct timespec rem;

while (nanosleep(&req, &rem) != 0) {
expect(errno == EINTR);
req = rem;
}

total_wait_ms += delay_ms;
delay_ms *= 2;
}

die("Failed to %s clipmenud after %d retries\n",
Expand Down

0 comments on commit 30fa2c3

Please sign in to comment.