Commit c257f892fd

LemonBoy <thatlemon@gmail.com>
2019-12-16 10:56:53
Revert "Revert "Use eventfd in ChildProcess on Linux""
This reverts commit 2c7a2aefbfd0dbab190f912b4fbcbda96fb5ac44.
1 parent 2c7a2ae
Changed files (1)
lib/std/child_process.zig
@@ -280,10 +280,7 @@ pub const ChildProcess = struct {
     }
 
     fn cleanupAfterWait(self: *ChildProcess, status: u32) !Term {
-        defer {
-            os.close(self.err_pipe[0]);
-            os.close(self.err_pipe[1]);
-        }
+        defer destroyPipe(self.err_pipe);
 
         // Write maxInt(ErrInt) to the write end of the err_pipe. This is after
         // waitpid, so this write is guaranteed to be after the child
@@ -359,7 +356,16 @@ pub const ChildProcess = struct {
 
         // This pipe is used to communicate errors between the time of fork
         // and execve from the child process to the parent process.
-        const err_pipe = try os.pipe();
+        const err_pipe = blk: {
+            if (builtin.os == .linux) {
+                const fd = try os.eventfd(0, 0);
+                // There's no distinction between the readable and the writeable
+                // end with eventfd
+                break :blk [2]os.fd_t{ fd, fd };
+            } else {
+                break :blk try os.pipe();
+            }
+        };
         errdefer destroyPipe(err_pipe);
 
         const pid_result = try os.fork();
@@ -773,7 +779,7 @@ fn windowsMakePipeOut(rd: *?windows.HANDLE, wr: *?windows.HANDLE, sattr: *const
 
 fn destroyPipe(pipe: [2]os.fd_t) void {
     os.close(pipe[0]);
-    os.close(pipe[1]);
+    if (pipe[0] != pipe[1]) os.close(pipe[1]);
 }
 
 // Child of fork calls this to report an error to the fork parent.
@@ -787,12 +793,12 @@ const ErrInt = @IntType(false, @sizeOf(anyerror) * 8);
 
 fn writeIntFd(fd: i32, value: ErrInt) !void {
     const stream = &File.openHandle(fd).outStream().stream;
-    stream.writeIntNative(ErrInt, value) catch return error.SystemResources;
+    stream.writeIntNative(u64, @intCast(u64, value)) catch return error.SystemResources;
 }
 
 fn readIntFd(fd: i32) !ErrInt {
     const stream = &File.openHandle(fd).inStream().stream;
-    return stream.readIntNative(ErrInt) catch return error.SystemResources;
+    return @intCast(ErrInt, stream.readIntNative(u64) catch return error.SystemResources);
 }
 
 /// Caller must free result.