Ticket #7032: 7032.patch

File 7032.patch, 2.6 KB (added by pcapriotti, 2 years ago)
  • System/Posix/Unistd.hsc

    From ba7961f118f42ba9db7e5fba017270a257852ff3 Mon Sep 17 00:00:00 2001
    From: Paolo Capriotti <p.capriotti@gmail.com>
    Date: Mon, 2 Jul 2012 11:52:39 +0100
    Subject: [PATCH] Add a WARNING for sleep, and expand documentation.
    
    sleep doesn't really work on GHC because it is always immediately
    interrupted by SIGVTALRM used in the RTS.
    
    I explained the problem in a comment and added a WARNING pragma.
    
    usleep and nanosleep have a similar problem, but, since they have better
    precision, they can be restarted, so they are not as unusable as sleep.
    ---
     System/Posix/Unistd.hsc |   15 +++++++++++++--
     1 file changed, 13 insertions(+), 2 deletions(-)
    
    diff --git a/System/Posix/Unistd.hsc b/System/Posix/Unistd.hsc
    index 7312dae..dfd2673 100644
    a b foreign import ccall unsafe "uname" 
    9595-- | Sleep for the specified duration (in seconds).  Returns the time remaining 
    9696-- (if the sleep was interrupted by a signal, for example). 
    9797-- 
    98 -- GHC Note: the comment for 'usleep' also applies here. 
     98-- /GHC Note/: 'Control.Concurrent.threadDelay' is a better choice.  Since GHC 
     99-- uses signals for its internal clock, a call to 'sleep' will usually be 
     100-- interrupted immediately.  That makes 'sleep' unusable in a program compiled 
     101-- with GHC, unless the RTS timer is disabled (with @+RTS -V0@).  Furthermore, 
     102-- without the @-threaded@ option, 'sleep' will block all other user threads. 
     103-- Even with the @-threaded@ option, 'sleep' requires a full OS thread to 
     104-- itself.  'Control.Concurrent.threadDelay' has none of these shortcomings. 
    99105-- 
    100106sleep :: Int -> IO Int 
    101107sleep 0 = return 0 
    102108sleep secs = do r <- c_sleep (fromIntegral secs); return (fromIntegral r) 
    103109 
     110#ifdef __GLASGOW_HASKELL__ 
     111{-# WARNING sleep "This function has several shortcomings (see documentation). Please consider using Control.Concurrent.threadDelay instead." #-} 
     112#endif 
     113 
    104114foreign import ccall safe "sleep" 
    105115  c_sleep :: CUInt -> IO CUInt 
    106116 
    107117-- | Sleep for the specified duration (in microseconds). 
    108118-- 
    109 -- GHC Note: 'Control.Concurrent.threadDelay' is a better choice. 
     119-- /GHC Note/: 'Control.Concurrent.threadDelay' is a better choice. 
    110120-- Without the @-threaded@ option, 'usleep' will block all other user 
    111121-- threads.  Even with the @-threaded@ option, 'usleep' requires a 
    112122-- full OS thread to itself.  'Control.Concurrent.threadDelay' has 
    foreign import ccall safe "usleep" 
    134144 
    135145-- | Sleep for the specified duration (in nanoseconds) 
    136146-- 
     147-- /GHC Note/: the comment for 'usleep' also applies here. 
    137148nanosleep :: Integer -> IO () 
    138149#ifndef HAVE_NANOSLEEP 
    139150nanosleep = error "nanosleep: not available on this platform"