Multithreading – you can wait for network on windows Socket. Accept Haskell or Haskell OS thread?

-- thread A
-- thread A
t <- forkIO $do
   _ <- accept listener -- blocks
-- thread B
killThread t

On Linux (possibly also on OS X and FreeBSD), but not on windows (using RTS - N4 - RTS, etc.)

>What is the correct way to terminate thread a in this case? > Is there a way to fork thread a into a special mode that allows termination at the point where it prevents acceptance? > Will it help if a forks with forkos instead of forkio?

I noticed this wrong windows behavior only when a bug report warning

Solution

Interesting question!

You can't interrupt and block incoming calls, so I'm a little surprised that you can interrupt threads on Linux Moreover, forkos does not help - only allows external code to allocate thread local storage, but has nothing to do with blocking behavior But recall that acceptance can be set to non blocking:

In the network library for POSIX systems This allows you to accept interrupts

An interesting note about windows:

-- On Windows,our sockets are not put in non-blocking mode (non-blocking
-- is not supported for regular file descriptors on Windows,and it would
-- be a pain to support it only for sockets).  So there are two cases:
--
--  - the threaded RTS uses safe calls for socket operations to get
--    non-blocking I/O,just like the rest of the I/O library
--
--  - with the non-threaded RTS,only some operations on sockets will be
--    non-blocking.  Reads and writes go through the normal async I/O
--    system.  accept() uses asyncDoProc so is non-blocking.  A handful
--    of others (recvFrom,sendFd,recvFd) will block all threads - if this
--    is a problem,-threaded is the workaround.

Now, accept the runtime thread on windows and use accept_ Safe (allow other threads to do this) – but it does not put the socket in non blocking mode:

accept sock@(MkSocket s family stype protocol status) = do
 currentStatus <- readMVar status
 okay <- sIsAcceptable sock
 if not okay
   then
     ioError (userError ("accept: can't perform accept on socket (" ++ (show (family,stype,protocol)) ++") in status " ++
     show currentStatus))
   else do
     let sz = sizeOfSockAddrByFamily family
     allocaBytes sz $\ sockaddr -> do

#if defined(mingw32_HOST_OS) && defined(__GLASGOW_HASKELL__)
     new_sock <-
    if threaded
       then with (fromIntegral sz) $\ ptr_len ->
          throwErrnoIfMinus1Retry "Network.socket.accept" $
            c_accept_safe s sockaddr ptr_len
       else do
            paramData <- c_newAcceptParams s (fromIntegral sz) sockaddr
            rc        <- asyncDoProc c_acceptDoProc paramData
            new_sock  <- c_acceptNewSock    paramData
            c_free paramData
            when (rc /= 0)
                 (ioError (errnoToIOError "Network.socket.accept" (Errno (fromIntegral rc)) Nothing Nothing))
        return new_sock

Since 2005, the version using - threaded on windows has explicitly used an accept call marked as safe, allowing other threads to make progress, but not setting the socket itself to non blocking mode (so the calling thread is blocked)

To solve it, I see two options:

>Develop how to accept non blocking calls on windows and patch the network library – see, for example, snap or yesodhere to see if they have been resolved. > Use some kind of monitoring thread to forge epoll to monitor the progress of blocked sub threads

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>