summaryrefslogtreecommitdiff
path: root/init/firmware_handler.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'init/firmware_handler.cpp')
-rw-r--r--init/firmware_handler.cpp28
1 files changed, 22 insertions, 6 deletions
diff --git a/init/firmware_handler.cpp b/init/firmware_handler.cpp
index 1471aeb47..844c6051f 100644
--- a/init/firmware_handler.cpp
+++ b/init/firmware_handler.cpp
@@ -18,6 +18,7 @@
#include <fcntl.h>
#include <sys/sendfile.h>
+#include <sys/wait.h>
#include <unistd.h>
#include <string>
@@ -103,14 +104,29 @@ void HandleFirmwareEvent(const Uevent& uevent) {
if (uevent.subsystem != "firmware" || uevent.action != "add") return;
// Loading the firmware in a child means we can do that in parallel...
- // (We ignore SIGCHLD rather than wait for our children.)
+ // We double fork instead of waiting for these processes.
pid_t pid = fork();
+ if (pid == -1) {
+ PLOG(ERROR) << "could not fork to process firmware event for " << uevent.firmware;
+ return;
+ }
+
if (pid == 0) {
- Timer t;
- ProcessFirmwareEvent(uevent);
- LOG(INFO) << "loading " << uevent.path << " took " << t;
+ pid = fork();
+ if (pid == -1) {
+ PLOG(ERROR) << "could not fork a sceond time to process firmware event for "
+ << uevent.firmware;
+ _exit(EXIT_FAILURE);
+ }
+ if (pid == 0) {
+ Timer t;
+ ProcessFirmwareEvent(uevent);
+ LOG(INFO) << "loading " << uevent.path << " took " << t;
+ _exit(EXIT_SUCCESS);
+ }
+
_exit(EXIT_SUCCESS);
- } else if (pid == -1) {
- PLOG(ERROR) << "could not fork to process firmware event for " << uevent.firmware;
}
+
+ waitpid(pid, nullptr, 0);
}