Skip to content

Commit 9c50f37

Browse files
mpickeringsheaf
authored andcommitted
Add semWaitInterruptible
The semWaitInterruptible function allows us to start a thread that blocks on the semaphore but can be interrupted.
1 parent b085646 commit 9c50f37

File tree

1 file changed

+18
-2
lines changed

1 file changed

+18
-2
lines changed

System/Posix/Semaphore.hsc

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
{-# LANGUAGE Safe #-}
22
{-# LANGUAGE CApiFFI #-}
3+
{-# LANGUAGE InterruptibleFFI #-}
34
-----------------------------------------------------------------------------
45
-- |
56
-- Module : System.Posix.Semaphore
@@ -16,7 +17,7 @@
1617

1718
module System.Posix.Semaphore
1819
(OpenSemFlags(..), Semaphore(),
19-
semOpen, semUnlink, semWait, semTryWait, semThreadWait,
20+
semOpen, semUnlink, semWait, semWaitInterruptible, semTryWait, semThreadWait,
2021
semPost, semGetValue)
2122
where
2223

@@ -79,6 +80,20 @@ semWait (Semaphore fptr) = withForeignPtr fptr semWait'
7980
where semWait' sem = throwErrnoIfMinus1Retry_ "semWait" $
8081
sem_wait sem
8182

83+
-- | Lock the semaphore, blocking until it becomes available.
84+
--
85+
-- Unlike 'semWait', this wait operation can be interrupted with an
86+
-- EINTR signal.
87+
semWaitInterruptible :: Semaphore -> IO Bool
88+
semWaitInterruptible (Semaphore fptr) = withForeignPtr fptr semWait'
89+
where semWait' sem =
90+
do res <- sem_wait_interruptible sem
91+
if res == 0 then return True
92+
else do errno <- getErrno
93+
if errno == eINTR
94+
then return False
95+
else throwErrno "semWaitInterrruptible"
96+
8297
-- | Attempt to lock the semaphore without blocking. Immediately return
8398
-- False if it is not available.
8499
semTryWait :: Semaphore -> IO Bool
@@ -132,9 +147,10 @@ foreign import capi safe "semaphore.h sem_close"
132147
sem_close :: Ptr () -> IO CInt
133148
foreign import capi safe "semaphore.h sem_unlink"
134149
sem_unlink :: CString -> IO CInt
135-
136150
foreign import capi safe "semaphore.h sem_wait"
137151
sem_wait :: Ptr () -> IO CInt
152+
foreign import capi interruptible "semaphore.h sem_wait"
153+
sem_wait_interruptible :: Ptr () -> IO CInt
138154
foreign import capi safe "semaphore.h sem_trywait"
139155
sem_trywait :: Ptr () -> IO CInt
140156
foreign import capi safe "semaphore.h sem_post"

0 commit comments

Comments
 (0)