diff options
Diffstat (limited to 'src/udev')
-rw-r--r-- | src/udev/udevd.c | 25 |
1 files changed, 13 insertions, 12 deletions
diff --git a/src/udev/udevd.c b/src/udev/udevd.c index 1eb7b779eb..4ab3216ab7 100644 --- a/src/udev/udevd.c +++ b/src/udev/udevd.c @@ -168,7 +168,6 @@ static void worker_list_cleanup(struct udev *udev) { static void worker_spawn(struct event *event) { struct udev *udev = event->udev; - struct worker *worker; struct udev_monitor *worker_monitor; pid_t pid; @@ -180,15 +179,6 @@ static void worker_spawn(struct event *event) { udev_monitor_allow_unicast_sender(worker_monitor, monitor); udev_monitor_enable_receiving(worker_monitor); - worker = new0(struct worker, 1); - if (worker == NULL) { - udev_monitor_unref(worker_monitor); - return; - } - /* worker + event reference */ - worker->refcount = 2; - worker->udev = udev; - pid = fork(); switch (pid) { case 0: { @@ -203,7 +193,6 @@ static void worker_spawn(struct event *event) { dev = event->dev; event->dev = NULL; - free(worker); worker_list_cleanup(udev); event_queue_cleanup(udev, EVENT_UNDEF); udev_monitor_unref(monitor); @@ -392,10 +381,21 @@ out: case -1: udev_monitor_unref(worker_monitor); event->state = EVENT_QUEUED; - free(worker); log_error_errno(errno, "fork of child failed: %m"); break; default: + { + struct worker *worker; + + worker = new0(struct worker, 1); + if (!worker) { + udev_monitor_unref(worker_monitor); + return; + } + + /* worker + event reference */ + worker->refcount = 2; + worker->udev = udev; /* close monitor, but keep address around */ udev_monitor_disconnect(worker_monitor); worker->monitor = worker_monitor; @@ -410,6 +410,7 @@ out: log_debug("seq %llu forked new worker ["PID_FMT"]", udev_device_get_seqnum(event->dev), pid); break; } + } } static void event_run(struct event *event) { |