Skip to content

Commit 910a7ab

Browse files
authored
Guard against lack of sem_getvalue (#232)
Darwin often lacks this function.
1 parent cf5410e commit 910a7ab

File tree

2 files changed

+21
-4
lines changed

2 files changed

+21
-4
lines changed

System/Posix/Semaphore.hsc

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,18 +20,24 @@ module System.Posix.Semaphore
2020
semPost, semGetValue)
2121
where
2222

23+
#include "HsUnix.h"
2324
#include <semaphore.h>
2425
#include <fcntl.h>
2526

2627
import Foreign.C
2728
import Foreign.ForeignPtr hiding (newForeignPtr)
2829
import Foreign.Concurrent
29-
import Foreign.Marshal
3030
import Foreign.Ptr
31-
import Foreign.Storable
3231
import System.Posix.Types
3332
import Control.Concurrent
3433
import Data.Bits
34+
#if !defined(HAVE_SEM_GETVALUE)
35+
import System.IO.Error ( ioeSetLocation )
36+
import GHC.IO.Exception ( unsupportedOperation )
37+
#else
38+
import Foreign.Marshal
39+
import Foreign.Storable
40+
#endif
3541

3642
data OpenSemFlags = OpenSemFlags { semCreate :: Bool,
3743
-- ^ If true, create the semaphore if it
@@ -102,15 +108,24 @@ semPost (Semaphore fptr) = withForeignPtr fptr semPost'
102108

103109
-- | Return the semaphore's current value.
104110
semGetValue :: Semaphore -> IO Int
111+
#ifdef HAVE_SEM_GETVALUE
105112
semGetValue (Semaphore fptr) = withForeignPtr fptr semGetValue'
106113
where semGetValue' sem = alloca (semGetValue_ sem)
107114

115+
108116
semGetValue_ :: Ptr () -> Ptr CInt -> IO Int
109117
semGetValue_ sem ptr = do throwErrnoIfMinus1Retry_ "semGetValue" $
110118
sem_getvalue sem ptr
111119
cint <- peek ptr
112120
return $ fromEnum cint
113121

122+
foreign import capi safe "semaphore.h sem_getvalue"
123+
sem_getvalue :: Ptr () -> Ptr CInt -> IO Int
124+
#else
125+
{-# WARNING semGetValue "operation will throw 'IOError' \"unsupported operation\" (CPP guard: @#if HAVE_SEM_GETVALUE@)" #-}
126+
semGetValue _ = ioError (ioeSetLocation unsupportedOperation "semGetValue")
127+
#endif
128+
114129
foreign import capi safe "semaphore.h sem_open"
115130
sem_open :: CString -> CInt -> CMode -> CUInt -> IO (Ptr ())
116131
foreign import capi safe "semaphore.h sem_close"
@@ -124,5 +139,3 @@ foreign import capi safe "semaphore.h sem_trywait"
124139
sem_trywait :: Ptr () -> IO CInt
125140
foreign import capi safe "semaphore.h sem_post"
126141
sem_post :: Ptr () -> IO CInt
127-
foreign import capi safe "semaphore.h sem_getvalue"
128-
sem_getvalue :: Ptr () -> Ptr CInt -> IO Int

configure.ac

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -264,6 +264,10 @@ AC_SEARCH_LIBS(sem_close, pthread,
264264
[EXTRA_LIBS="$EXTRA_LIBS $ac_lib"],
265265
[AC_MSG_NOTICE([Not found])])
266266

267+
AC_CHECK_DECLS([sem_getvalue],[AC_DEFINE([HAVE_SEM_GETVALUE],[1],[Define to 1 if you have the `sem_getvalue' function.])],[],[AC_INCLUDES_DEFAULT
268+
#include <semaphore.h>
269+
])
270+
267271
AC_SUBST([EXTRA_LIBS])
268272
AC_CONFIG_FILES([unix.buildinfo])
269273

0 commit comments

Comments
 (0)