WORKER_RUNNING,
WORKER_IDLE,
WORKER_KILLED,
+ WORKER_KILLING,
};
struct worker {
return 0;
}
-static void manager_kill_workers(Manager *manager) {
+static void manager_kill_workers(Manager *manager, bool force) {
struct worker *worker;
assert(manager);
if (worker->state == WORKER_KILLED)
continue;
+ if (worker->state == WORKER_RUNNING && !force) {
+ worker->state = WORKER_KILLING;
+ continue;
+ }
+
worker->state = WORKER_KILLED;
(void) kill(worker->pid, SIGTERM);
}
/* discard queued events and kill workers */
event_queue_cleanup(manager, EVENT_QUEUED);
- manager_kill_workers(manager);
+ manager_kill_workers(manager, true);
}
/* reload requested, HUP signal received, rules changed, builtin changed */
"RELOADING=1\n"
"STATUS=Flushing configuration...");
- manager_kill_workers(manager);
+ manager_kill_workers(manager, false);
manager->rules = udev_rules_free(manager->rules);
udev_builtin_exit();
assert(manager);
log_debug("Cleanup idle workers");
- manager_kill_workers(manager);
+ manager_kill_workers(manager, false);
return 1;
}
continue;
}
- if (worker->state != WORKER_KILLED)
+ if (worker->state == WORKER_KILLING) {
+ worker->state = WORKER_KILLED;
+ (void) kill(worker->pid, SIGTERM);
+ } else if (worker->state != WORKER_KILLED)
worker->state = WORKER_IDLE;
/* worker returned */
log_debug("Received udev control message (SET_LOG_LEVEL), setting log_level=%i", value->intval);
log_set_max_level(value->intval);
manager->log_level = value->intval;
- manager_kill_workers(manager);
+ manager_kill_workers(manager, false);
break;
case UDEV_CTRL_STOP_EXEC_QUEUE:
log_debug("Received udev control message (STOP_EXEC_QUEUE)");
}
key = val = NULL;
- manager_kill_workers(manager);
+ manager_kill_workers(manager, false);
break;
}
case UDEV_CTRL_SET_CHILDREN_MAX: