{-# LINE 1 "libraries\\ghc-internal\\src\\GHC\\Internal\\ConsoleHandler.hsc" #-}
{-# LANGUAGE Trustworthy #-}
{-# LANGUAGE NoImplicitPrelude #-}
{-# LANGUAGE CPP #-}
module GHC.Internal.ConsoleHandler
{-# LINE 28 "libraries\\ghc-internal\\src\\GHC\\Internal\\ConsoleHandler.hsc" #-}
( Handler(..)
, installHandler
, ConsoleEvent(..)
) where
import GHC.Internal.Base
import GHC.Internal.Foreign.C.Types
import GHC.Internal.Foreign.Marshal.Alloc
import GHC.Internal.Foreign.Ptr
import GHC.Internal.Foreign.Storable
import GHC.Internal.Stable
import GHC.Internal.Conc.IO
import GHC.Internal.Control.Concurrent.MVar
data Handler
= Default
| Ignore
| Catch (ConsoleEvent -> IO ())
installHandler :: Handler -> IO Handler
installHandler handler
| threaded =
modifyMVar win32ConsoleHandler $ \old_h -> do
(new_h,rc) <-
case handler of
Default -> do
r <- rts_installHandler STG_SIG_DFL nullPtr
return (no_handler, r)
Ignore -> do
r <- rts_installHandler STG_SIG_IGN nullPtr
return (no_handler, r)
Catch h -> do
r <- rts_installHandler STG_SIG_HAN nullPtr
return (h, r)
prev_handler <-
case rc of
STG_SIG_DFL -> return Default
STG_SIG_IGN -> return Ignore
STG_SIG_HAN -> return (Catch old_h)
_ -> errorWithoutStackTrace "installHandler: Bad threaded rc value"
return (new_h, prev_handler)
| otherwise =
alloca $ \ p_sp -> do
rc <-
case handler of
Default -> rts_installHandler STG_SIG_DFL p_sp
Ignore -> rts_installHandler STG_SIG_IGN p_sp
Catch h -> do
v <- newStablePtr (toHandler h)
poke p_sp v
rts_installHandler STG_SIG_HAN p_sp
case rc of
STG_SIG_DFL -> return Default
STG_SIG_IGN -> return Ignore
STG_SIG_HAN -> do
osptr <- peek p_sp
oldh <- deRefStablePtr osptr
freeStablePtr osptr
return (Catch (\ ev -> oldh (fromConsoleEvent ev)))
_ -> errorWithoutStackTrace "installHandler: Bad non-threaded rc value"
where
fromConsoleEvent ev =
case ev of
ControlC -> 0
{-# LINE 125 "libraries\\ghc-internal\\src\\GHC\\Internal\\ConsoleHandler.hsc" #-}
Break -> 1
{-# LINE 126 "libraries\\ghc-internal\\src\\GHC\\Internal\\ConsoleHandler.hsc" #-}
Close -> 2
{-# LINE 127 "libraries\\ghc-internal\\src\\GHC\\Internal\\ConsoleHandler.hsc" #-}
Logoff -> 5
{-# LINE 128 "libraries\\ghc-internal\\src\\GHC\\Internal\\ConsoleHandler.hsc" #-}
Shutdown -> 6
{-# LINE 129 "libraries\\ghc-internal\\src\\GHC\\Internal\\ConsoleHandler.hsc" #-}
toHandler hdlr ev = do
case toWin32ConsoleEvent ev of
Just x -> hdlr x >> rts_ConsoleHandlerDone ev
Nothing -> return ()
no_handler = errorWithoutStackTrace "win32ConsoleHandler"
foreign import ccall unsafe "rtsSupportsBoundThreads" threaded :: Bool
foreign import ccall unsafe "RtsExternal.h rts_InstallConsoleEvent"
rts_installHandler :: CInt -> Ptr (StablePtr (CInt -> IO ())) -> IO CInt
foreign import ccall unsafe "RtsExternal.h rts_ConsoleHandlerDone"
rts_ConsoleHandlerDone :: CInt -> IO ()
{-# LINE 147 "libraries\\ghc-internal\\src\\GHC\\Internal\\ConsoleHandler.hsc" #-}