|
1 | 1 | {-# LANGUAGE Safe #-}
|
2 | 2 | {-# LANGUAGE CApiFFI #-}
|
| 3 | +{-# LANGUAGE InterruptibleFFI #-} |
3 | 4 | -----------------------------------------------------------------------------
|
4 | 5 | -- |
|
5 | 6 | -- Module : System.Posix.Semaphore
|
|
16 | 17 |
|
17 | 18 | module System.Posix.Semaphore
|
18 | 19 | (OpenSemFlags(..), Semaphore(),
|
19 |
| - semOpen, semUnlink, semWait, semTryWait, semThreadWait, |
| 20 | + semOpen, semUnlink, semWait, semWaitInterruptible, semTryWait, semThreadWait, |
20 | 21 | semPost, semGetValue)
|
21 | 22 | where
|
22 | 23 |
|
@@ -86,6 +87,20 @@ semWait (Semaphore fptr) = withForeignPtr fptr semWait'
|
86 | 87 | where semWait' sem = throwErrnoIfMinus1Retry_ "semWait" $
|
87 | 88 | sem_wait sem
|
88 | 89 |
|
| 90 | +-- | Lock the semaphore, blocking until it becomes available. |
| 91 | +-- |
| 92 | +-- Unlike 'semWait', this wait operation can be interrupted with |
| 93 | +-- an asynchronous exception (e.g. a call to 'throwTo' from another thread). |
| 94 | +semWaitInterruptible :: Semaphore -> IO Bool |
| 95 | +semWaitInterruptible (Semaphore fptr) = withForeignPtr fptr semWait' |
| 96 | + where semWait' sem = |
| 97 | + do res <- sem_wait_interruptible sem |
| 98 | + if res == 0 then return True |
| 99 | + else do errno <- getErrno |
| 100 | + if errno == eINTR |
| 101 | + then return False |
| 102 | + else throwErrno "semWaitInterrruptible" |
| 103 | + |
89 | 104 | -- | Attempt to lock the semaphore without blocking. Immediately return
|
90 | 105 | -- False if it is not available.
|
91 | 106 | semTryWait :: Semaphore -> IO Bool
|
@@ -145,9 +160,10 @@ foreign import capi safe "semaphore.h sem_close"
|
145 | 160 | sem_close :: Ptr () -> IO CInt
|
146 | 161 | foreign import capi safe "semaphore.h sem_unlink"
|
147 | 162 | sem_unlink :: CString -> IO CInt
|
148 |
| - |
149 | 163 | foreign import capi safe "semaphore.h sem_wait"
|
150 | 164 | sem_wait :: Ptr () -> IO CInt
|
| 165 | +foreign import capi interruptible "semaphore.h sem_wait" |
| 166 | + sem_wait_interruptible :: Ptr () -> IO CInt |
151 | 167 | foreign import capi safe "semaphore.h sem_trywait"
|
152 | 168 | sem_trywait :: Ptr () -> IO CInt
|
153 | 169 | foreign import capi safe "semaphore.h sem_post"
|
|
0 commit comments