about summary refs log tree commit diff
diff options
context:
space:
mode:
authorsternenseemann <0rpkxez4ksa01gb3typccl0i@systemli.org>2021-03-15 01:20:09 +0100
committersterni <sternenseemann@systemli.org>2021-03-15 01:47:32 +0100
commit695b508b94dc20ef6f1a169e2456557e825d8945 (patch)
treefec09b9e89e03bb7c0862cbca7ccc4bbe72af8eb
parentaa8a75a877bfc2c177aabe5eef8103304fab77c7 (diff)
fix(Spacecookie.Systemd): keep Socket MVar populated
Mimic the behavior of 'close' in toFd: replace the old file descriptor
with (-1). This ensures that further calls on the 'Socket' are “safe” in
a sense as they won't block indefinetely. Instead they will throw an
exception as if close was called on the Socket.
-rw-r--r--server/Network/Spacecookie/Systemd.hs8
1 files changed, 6 insertions, 2 deletions
diff --git a/server/Network/Spacecookie/Systemd.hs b/server/Network/Spacecookie/Systemd.hs
index 22ab0aa..2243d01 100644
--- a/server/Network/Spacecookie/Systemd.hs
+++ b/server/Network/Spacecookie/Systemd.hs
@@ -8,7 +8,7 @@ module Network.Spacecookie.Systemd
   , SystemdException (..)
   ) where
 
-import Control.Concurrent.MVar (newMVar, takeMVar, mkWeakMVar)
+import Control.Concurrent.MVar (newMVar, swapMVar, mkWeakMVar)
 import Control.Exception.Base
 import Control.Monad (when)
 import Data.Maybe (fromMaybe)
@@ -36,8 +36,12 @@ closeFd fd = do
     $ mkIOError userErrorType "Could not close File Descriptor" Nothing Nothing
 
 -- | Irreversibly convert a 'Socket' into an 'Fd'.
+--   Invalidates the socket and returns the file descriptor
+--   contained within it.
 toFd :: Socket a b c -> IO Fd
-toFd (Socket mvar) = fmap (Fd . fromIntegral) (takeMVar mvar)
+toFd (Socket mvar) = fmap (Fd . fromIntegral) (swapMVar mvar (-1))
+-- putting an invalid file descriptor into the 'MVar' makes
+-- the 'Socket' appear to System.Socket as if it were closed
 
 -- | Create an 'Socket' from an 'Fd'. This action is unsafe
 --   since the type of the socket is not checked meaning that