File tree Expand file tree Collapse file tree 4 files changed +40
-4
lines changed Expand file tree Collapse file tree 4 files changed +40
-4
lines changed Original file line number Diff line number Diff line change @@ -39,6 +39,13 @@ import Foreign.Marshal
39
39
import Foreign.Storable
40
40
#endif
41
41
42
+ #if __GLASGOW_HASKELL__ >= 902
43
+ import System.Posix.Internals (hostIsThreaded )
44
+ #else
45
+ hostIsThreaded :: Bool
46
+ hostIsThreaded = False
47
+ #endif
48
+
42
49
data OpenSemFlags = OpenSemFlags { semCreate :: Bool ,
43
50
-- ^ If true, create the semaphore if it
44
51
-- does not yet exist.
@@ -96,9 +103,15 @@ semTryWait (Semaphore fptr) = withForeignPtr fptr semTrywait'
96
103
-- semWait, this will block only the current thread rather than the
97
104
-- entire process.
98
105
semThreadWait :: Semaphore -> IO ()
99
- semThreadWait sem = do res <- semTryWait sem
100
- (if res then return ()
101
- else ( do { yield; semThreadWait sem } ))
106
+ semThreadWait sem
107
+ -- N.B. semWait can be safely used in the case of the threaded runtime, where
108
+ -- the safe foreign call will be performed in its own thread, thereby not
109
+ -- blocking the process.
110
+ | hostIsThreaded = semWait sem
111
+ | otherwise = do
112
+ res <- semTryWait sem
113
+ if res then return ()
114
+ else do yield >> semThreadWait sem
102
115
103
116
-- | Unlock the semaphore.
104
117
semPost :: Semaphore -> IO ()
Original file line number Diff line number Diff line change @@ -8,7 +8,7 @@ const my_execFile = util.promisify(child_process.execFile);
8
8
let warns_count = 0 ;
9
9
for ( const f of await fs . promises . readdir ( "tests" ) ) {
10
10
// odd linker errors
11
- if ( f === "Semaphore001.hs" ) continue ;
11
+ if ( f . startsWith ( 'Semaphore' ) ) continue ;
12
12
// Find self-contained test cases (aka doesn't rely on tasty)
13
13
if ( ! f . endsWith ( ".hs" ) ) continue ;
14
14
const s = await fs . promises . readFile ( `tests/${ f } ` , "utf-8" ) ;
Original file line number Diff line number Diff line change
1
+ module Main (main ) where
2
+
3
+ import Control.Concurrent
4
+ import System.Posix
5
+
6
+ main :: IO ()
7
+ main = do
8
+ sem <- semOpen " /test" OpenSemFlags {semCreate = True , semExclusive = False } stdFileMode 0
9
+ forkIO $ do
10
+ threadDelay (1000 * 1000 )
11
+ semPost sem
12
+
13
+ -- This should succeed after 1 second.
14
+ semThreadWait sem
15
+ semPost sem
Original file line number Diff line number Diff line change @@ -262,3 +262,11 @@ test-suite Semaphore001
262
262
default-language : Haskell2010
263
263
build-depends : base, unix
264
264
ghc-options : -Wall
265
+
266
+ test-suite Semaphore002
267
+ hs-source-dirs : tests
268
+ main-is : Semaphore002.hs
269
+ type : exitcode-stdio-1.0
270
+ default-language : Haskell2010
271
+ build-depends : base, unix
272
+ ghc-options : -Wall -threaded
You can’t perform that action at this time.
0 commit comments