[Git][ghc/ghc][master] 3 commits: JS: use regular mask for blocking IO

Marge Bot (@marge-bot) gitlab at gitlab.haskell.org
Thu Jun 15 07:13:55 UTC 2023



Marge Bot pushed to branch master at Glasgow Haskell Compiler / GHC


Commits:
59c9065b by Luite Stegeman at 2023-06-15T03:13:37-04:00
JS: use regular mask for blocking IO

Blocking IO used uninterruptibleMask which should make any thread
blocked on IO unreachable by async exceptions (such as those from
timeout). This changes it to a regular mask.

It's important to note that the nodejs runtime does not actually
interrupt the blocking IO when the Haskell thread receives an
async exception, and that file positions may be updated and buffers
may be written after the Haskell thread has already resumed.

Any file descriptor affected by an async exception interruption
should therefore be used with caution.

- - - - -
907c06c3 by Luite Stegeman at 2023-06-15T03:13:37-04:00
JS: nodejs: do not set 'readable' handler on stdin at startup

The Haskell runtime used to install a 'readable' handler on stdin
at startup in nodejs. This would cause the nodejs system to start
buffering the stream, causing data loss if the stdin file
descriptor is passed to another process.

This change delays installation of the 'readable' handler until
the first read of stdin by Haskell code.

- - - - -
a54b40a9 by Luite Stegeman at 2023-06-15T03:13:37-04:00
JS: reserve one more virtual (negative) file descriptor

This is needed for upcoming support of the process package

- - - - -


2 changed files:

- libraries/base/GHC/IO/FD.hs
- libraries/base/jsbits/base.js


Changes:

=====================================
libraries/base/GHC/IO/FD.hs
=====================================
@@ -571,7 +571,7 @@ indicates that there's no data, we call threadWaitRead.
 readRawBufferPtr :: String -> FD -> Ptr Word8 -> Int -> CSize -> IO Int
 readRawBufferPtr loc !fd !buf !off !len
 #if defined(javascript_HOST_ARCH)
-  = fmap fromIntegral . uninterruptibleMask_ $
+  = fmap fromIntegral . mask_ $
     throwErrnoIfMinus1 loc (c_read (fdFD fd) (buf `plusPtr` off) len)
 #else
   | isNonBlocking fd = unsafe_read -- unsafe is ok, it can't block
@@ -593,7 +593,7 @@ readRawBufferPtr loc !fd !buf !off !len
 readRawBufferPtrNoBlock :: String -> FD -> Ptr Word8 -> Int -> CSize -> IO Int
 readRawBufferPtrNoBlock loc !fd !buf !off !len
 #if defined(javascript_HOST_ARCH)
-  = uninterruptibleMask_ $ do
+  = mask_ $ do
       r <- throwErrnoIfMinus1 loc (c_read (fdFD fd) (buf `plusPtr` off) len)
       case r of
        (-1) -> return 0
@@ -618,7 +618,7 @@ readRawBufferPtrNoBlock loc !fd !buf !off !len
 writeRawBufferPtr :: String -> FD -> Ptr Word8 -> Int -> CSize -> IO CInt
 writeRawBufferPtr loc !fd !buf !off !len
 #if defined(javascript_HOST_ARCH)
-  = fmap fromIntegral . uninterruptibleMask_ $
+  = fmap fromIntegral . mask_ $
     throwErrnoIfMinus1 loc (c_write (fdFD fd) (buf `plusPtr` off) len)
 #else
   | isNonBlocking fd = unsafe_write -- unsafe is ok, it can't block
@@ -638,7 +638,7 @@ writeRawBufferPtr loc !fd !buf !off !len
 writeRawBufferPtrNoBlock :: String -> FD -> Ptr Word8 -> Int -> CSize -> IO CInt
 writeRawBufferPtrNoBlock loc !fd !buf !off !len
 #if defined(javascript_HOST_ARCH)
-  = uninterruptibleMask_ $ do
+  = mask_ $ do
       r <- throwErrnoIfMinus1 loc (c_write (fdFD fd) (buf `plusPtr` off) len)
       case r of
         (-1) -> return 0


=====================================
libraries/base/jsbits/base.js
=====================================
@@ -664,8 +664,14 @@ if(h$isNode()) {
         });
     }
 
+    var h$base_stdinHandlerInstalled = false;
+
     h$base_readStdin = function(fd, fdo, buf, buf_offset, n, c) {
         TRACE_IO("read stdin")
+        if(!h$base_stdinHandlerInstalled) {
+            process.stdin.on('readable', h$base_process_stdin);
+            h$base_stdinHandlerInstalled = true;
+        }
         h$base_stdin_waiting.enqueue({buf: buf, off: buf_offset, n: n, c: c});
         h$base_process_stdin();
     }
@@ -720,7 +726,6 @@ if(h$isNode()) {
         c(0);
     }
 
-    process.stdin.on('readable', h$base_process_stdin);
     process.stdin.on('end', function() { h$base_stdin_eof = true; h$base_process_stdin(); });
 
     h$base_isattyStdin  = function() { return process.stdin.isTTY;  };
@@ -803,7 +808,7 @@ var h$base_stderr_fd =
   , refs:   1
   };
 
-var h$base_fdN = -2; // negative file descriptors are 'virtual', -1 is already used to indicated error
+var h$base_fdN = -3; // negative file descriptors are 'virtual', -1 and -2 are reserved
 var h$base_fds = [h$base_stdin_fd, h$base_stdout_fd, h$base_stderr_fd];
 
 function h$shutdownHaskellAndExit(code, fast) {



View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/469ff08b4c56491f42236a5d59fe3e85ee901657...a54b40a99018a32a3251b2ff5e36c0816b39999f

-- 
View it on GitLab: https://gitlab.haskell.org/ghc/ghc/-/compare/469ff08b4c56491f42236a5d59fe3e85ee901657...a54b40a99018a32a3251b2ff5e36c0816b39999f
You're receiving this email because of your account on gitlab.haskell.org.


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/ghc-commits/attachments/20230615/11258680/attachment-0001.html>


More information about the ghc-commits mailing list