{-# LANGUAGE Trustworthy #-}{-# LANGUAGE NoImplicitPrelude, ForeignFunctionInterface #-}moduleGHC.Conc.Signal(Signal,HandlerFun,setHandler,runHandlers)whereimportControl.Concurrent.MVar(MVar,newMVar,withMVar)importData.Dynamic(Dynamic)importData.Maybe(Maybe(..))importForeign.C.Types(CInt)importForeign.ForeignPtr(ForeignPtr)importForeign.StablePtr(castPtrToStablePtr,castStablePtrToPtr,deRefStablePtr,freeStablePtr,newStablePtr)importForeign.Ptr(Ptr,castPtr)importGHC.Arr(inRange)importGHC.BaseimportGHC.Conc.Sync(forkIO)importGHC.IO(mask_,unsafePerformIO)importGHC.IOArray(IOArray,boundsIOArray,newIOArray,unsafeReadIOArray,unsafeWriteIOArray)importGHC.Real(fromIntegral)importGHC.Word(Word8)-------------------------------------------------------------------------- Signal handlingtypeSignal=CIntmaxSig::IntmaxSig=64typeHandlerFun=ForeignPtrWord8->IO()-- Lock used to protect concurrent access to signal_handlers. Symptom-- of this race condition is GHC bug #1922, although that bug was on-- Windows a similar bug also exists on Unix.signal_handlers::MVar(IOArrayInt(Maybe(HandlerFun,Dynamic)))signal_handlers=unsafePerformIO$doarr<-newIOArray(0,maxSig)Nothingm<-newMVararrsharedCAFmgetOrSetGHCConcSignalSignalHandlerStore{-# NOINLINE signal_handlers #-}foreignimportccallunsafe"getOrSetGHCConcSignalSignalHandlerStore"getOrSetGHCConcSignalSignalHandlerStore::Ptra->IO(Ptra)setHandler::Signal->Maybe(HandlerFun,Dynamic)->IO(Maybe(HandlerFun,Dynamic))setHandlersighandler=doletint=fromIntegralsigwithMVarsignal_handlers$\arr->ifnot(inRange(boundsIOArrayarr)int)thenerror"GHC.Conc.setHandler: signal out of range"elsedoold<-unsafeReadIOArrayarrintunsafeWriteIOArrayarrinthandlerreturnoldrunHandlers::ForeignPtrWord8->Signal->IO()runHandlersp_infosig=doletint=fromIntegralsigwithMVarsignal_handlers$\arr->ifnot(inRange(boundsIOArrayarr)int)thenreturn()elsedohandler<-unsafeReadIOArrayarrintcasehandlerofNothing->return()Just(f,_)->do_<-forkIO(fp_info)return()-- Machinery needed to ensure that we only have one copy of certain-- CAFs in this module even when the base package is present twice, as-- it is when base is dynamically loaded into GHCi. The RTS keeps-- track of the single true value of the CAF, so even when the CAFs in-- the dynamically-loaded base package are reverted, nothing bad-- happens.--sharedCAF::a->(Ptra->IO(Ptra))->IOasharedCAFaget_or_set=mask_$dostable_ref<-newStablePtraletref=castPtr(castStablePtrToPtrstable_ref)ref2<-get_or_setrefifref==ref2thenreturnaelsedofreeStablePtrstable_refdeRefStablePtr(castPtrToStablePtr(castPtrref2))