From dc231d66ace794e1d9684cab155e44e191d15635 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Tue, 6 May 2025 19:23:53 +0900 Subject: [PATCH] udev: move timeout event sources from struct Event to struct Worker The timeout event sources are enabled only when the event is being processed by a worker, hence they are not necessary to be owned by the event. No effective functional change, just refactoring. --- src/udev/udev-manager.c | 96 +++++++++++++++++++++-------------------- 1 file changed, 50 insertions(+), 46 deletions(-) diff --git a/src/udev/udev-manager.c b/src/udev/udev-manager.c index 504fdf2abfc..d883e0f6720 100644 --- a/src/udev/udev-manager.c +++ b/src/udev/udev-manager.c @@ -67,9 +67,6 @@ typedef struct Event { usec_t retry_again_timeout_usec; sd_event_source *retry_event_source; - sd_event_source *timeout_warning_event; - sd_event_source *timeout_event; - bool dependencies_built; Set *blocker_events; Set *blocking_events; @@ -88,6 +85,8 @@ typedef struct Worker { Manager *manager; PidRef pidref; sd_event_source *child_event_source; + sd_event_source *timeout_warning_event_source; + sd_event_source *timeout_kill_event_source; union sockaddr_union address; WorkerState state; Event *event; @@ -126,8 +125,6 @@ static Event* event_free(Event *event) { sd_device_unref(event->dev); sd_event_source_unref(event->retry_event_source); - sd_event_source_unref(event->timeout_warning_event); - sd_event_source_unref(event->timeout_event); return mfree(event); } @@ -142,6 +139,8 @@ static Worker* worker_free(Worker *worker) { hashmap_remove(worker->manager->workers, &worker->pidref); sd_event_source_disable_unref(worker->child_event_source); + sd_event_source_unref(worker->timeout_warning_event_source); + sd_event_source_unref(worker->timeout_kill_event_source); pidref_done(&worker->pidref); event_free(worker->event); @@ -439,36 +438,33 @@ static int worker_new(Worker **ret, Manager *manager, sd_device_monitor *worker_ return 0; } -static int on_event_timeout(sd_event_source *s, uint64_t usec, void *userdata) { - Event *event = ASSERT_PTR(userdata); - - assert(event->manager); - assert(event->worker); - - (void) pidref_kill_and_sigcont(&event->worker->pidref, event->manager->config.timeout_signal); - event->worker->state = WORKER_KILLED; +static int on_worker_timeout_kill(sd_event_source *s, uint64_t usec, void *userdata) { + Worker *worker = ASSERT_PTR(userdata); + Manager *manager = ASSERT_PTR(worker->manager); + Event *event = ASSERT_PTR(worker->event); - log_device_error(event->dev, "Worker ["PID_FMT"] processing SEQNUM=%"PRIu64" killed.", event->worker->pidref.pid, event->seqnum); + (void) pidref_kill_and_sigcont(&worker->pidref, manager->config.timeout_signal); + worker->state = WORKER_KILLED; - return 1; + log_device_error(event->dev, "Worker ["PID_FMT"] processing SEQNUM=%"PRIu64" killed.", worker->pidref.pid, event->seqnum); + return 0; } -static int on_event_timeout_warning(sd_event_source *s, uint64_t usec, void *userdata) { - Event *event = ASSERT_PTR(userdata); - - assert(event->worker); - - log_device_warning(event->dev, "Worker ["PID_FMT"] processing SEQNUM=%"PRIu64" is taking a long time.", event->worker->pidref.pid, event->seqnum); +static int on_worker_timeout_warning(sd_event_source *s, uint64_t usec, void *userdata) { + Worker *worker = ASSERT_PTR(userdata); + Event *event = ASSERT_PTR(worker->event); - return 1; + log_device_warning(event->dev, "Worker ["PID_FMT"] processing SEQNUM=%"PRIu64" is taking a long time.", worker->pidref.pid, event->seqnum); + return 0; } static void worker_attach_event(Worker *worker, Event *event) { Manager *manager = ASSERT_PTR(ASSERT_PTR(worker)->manager); - sd_event *e = ASSERT_PTR(manager->event); assert(event); + assert(event->state == EVENT_QUEUED); assert(!event->worker); + assert(IN_SET(worker->state, WORKER_UNDEF, WORKER_IDLE)); assert(!worker->event); worker->state = WORKER_RUNNING; @@ -477,29 +473,46 @@ static void worker_attach_event(Worker *worker, Event *event) { event->worker = worker; (void) event_reset_time_relative( - e, - &event->timeout_warning_event, + manager->event, + &worker->timeout_warning_event_source, CLOCK_MONOTONIC, udev_warn_timeout(manager->config.timeout_usec), USEC_PER_SEC, - on_event_timeout_warning, - event, + on_worker_timeout_warning, + worker, EVENT_PRIORITY_WORKER_TIMER, - "event-timeout-warn", + "worker-timeout-warn", /* force_reset = */ true); (void) event_reset_time_relative( - e, - &event->timeout_event, CLOCK_MONOTONIC, + manager->event, + &worker->timeout_kill_event_source, + CLOCK_MONOTONIC, manager_kill_worker_timeout(manager), USEC_PER_SEC, - on_event_timeout, - event, + on_worker_timeout_kill, + worker, EVENT_PRIORITY_WORKER_TIMER, - "event-timeout-kill", + "worker-timeout-kill", /* force_reset = */ true); } +static Event* worker_detach_event(Worker *worker) { + assert(worker); + + Event *event = TAKE_PTR(worker->event); + if (event) + assert_se(TAKE_PTR(event->worker) == worker); + + if (worker->state != WORKER_KILLED) + worker->state = WORKER_IDLE; + + (void) event_source_disable(worker->timeout_warning_event_source); + (void) event_source_disable(worker->timeout_kill_event_source); + + return event; +} + static int worker_spawn(Manager *manager, Event *event) { int r; @@ -757,9 +770,6 @@ static void event_requeue(Event *event) { sd_device *dev = ASSERT_PTR(event->dev); - event->timeout_warning_event = sd_event_source_disable_unref(event->timeout_warning_event); - event->timeout_event = sd_event_source_disable_unref(event->timeout_event); - /* add a short delay to suppress busy loop */ r = sd_event_now(event->manager->event, CLOCK_BOOTTIME, &now_usec); if (r < 0) { @@ -802,10 +812,6 @@ static void event_requeue(Event *event) { goto fail; } - if (event->worker) - event->worker->event = NULL; - event->worker = NULL; - event->state = EVENT_QUEUED; return; @@ -1152,15 +1158,13 @@ static int on_worker_notify(sd_event_source *s, int fd, uint32_t revents, void * return 0; } + Event *event = worker_detach_event(worker); + if (strv_contains(l, "TRY_AGAIN=1")) /* Worker cannot lock the device. Requeue the event. */ - event_requeue(worker->event); + event_requeue(event); else - event_free(worker->event); - - /* Update the state of the worker. */ - if (worker->state != WORKER_KILLED) - worker->state = WORKER_IDLE; + event_free(event); return 0; } -- 2.47.3