1{-# LANGUAGE RankNTypes #-}
2-- | Unlifted "Control.Concurrent".
3--
4-- This module is not reexported by "UnliftIO",
5-- use it only if "UnliftIO.Async" is not enough.
6--
7-- @since 0.1.1.0
8module UnliftIO.Concurrent
9  (
10    -- * Concurrent Haskell
11    ThreadId,
12
13    -- * Basic concurrency operations
14    myThreadId, forkIO, forkWithUnmask, forkIOWithUnmask,  forkFinally, killThread, throwTo,
15
16    -- ** Threads with affinity
17    forkOn, forkOnWithUnmask, getNumCapabilities, setNumCapabilities,
18    threadCapability,
19
20    -- * Scheduling
21    yield,
22
23    -- ** Waiting
24    threadDelay, threadWaitRead, threadWaitWrite,
25
26    -- * Communication abstractions
27    module UnliftIO.MVar, module UnliftIO.Chan,
28
29    -- * Bound Threads
30    C.rtsSupportsBoundThreads, forkOS, isCurrentThreadBound, runInBoundThread,
31    runInUnboundThread,
32
33    -- * Weak references to ThreadIds
34    mkWeakThreadId
35  ) where
36
37import Control.Monad.IO.Class (MonadIO, liftIO)
38import System.Posix.Types (Fd)
39import System.Mem.Weak (Weak)
40import Control.Concurrent (ThreadId)
41import qualified Control.Concurrent as C
42import Control.Monad.IO.Unlift
43import UnliftIO.MVar
44import UnliftIO.Chan
45import UnliftIO.Exception (throwTo, SomeException)
46
47-- | Lifted version of 'C.myThreadId'.
48--
49-- @since 0.1.1.0
50myThreadId :: MonadIO m => m ThreadId
51myThreadId = liftIO C.myThreadId
52{-# INLINABLE myThreadId #-}
53
54-- | Unlifted version of 'C.forkIO'.
55--
56-- @since 0.1.1.0
57forkIO :: MonadUnliftIO m => m () -> m ThreadId
58forkIO m = withRunInIO $ \run -> C.forkIO $ run m
59{-# INLINABLE forkIO #-}
60
61-- | Unlifted version of 'C.forkIOWithUnmask'.
62--
63-- @since 0.2.11
64forkIOWithUnmask :: MonadUnliftIO m => ((forall a. m a -> m a) -> m ()) -> m ThreadId
65forkIOWithUnmask m =
66  withRunInIO $ \run -> C.forkIOWithUnmask $ \unmask -> run $ m $ liftIO . unmask . run
67{-# INLINABLE forkIOWithUnmask #-}
68
69-- | Please use 'forkIOWithUnmask' instead. This function has been deprecated
70-- in release 0.2.11 and will be removed in the next major release.
71--
72-- @since 0.1.1.0
73forkWithUnmask :: MonadUnliftIO m => ((forall a. m a -> m a) -> m ()) -> m ThreadId
74forkWithUnmask = forkIOWithUnmask
75{-# INLINABLE forkWithUnmask #-}
76{-# DEPRECATED forkWithUnmask "forkWithUnmask has been renamed to forkIOWithUnmask" #-}
77
78-- | Unlifted version of 'C.forkFinally'.
79--
80-- @since 0.1.1.0
81forkFinally :: MonadUnliftIO m => m a -> (Either SomeException a -> m ()) -> m ThreadId
82forkFinally m1 m2 = withRunInIO $ \run -> C.forkFinally (run m1) $ run . m2
83{-# INLINABLE forkFinally #-}
84
85-- | Lifted version of 'C.killThread'.
86--
87-- @since 0.1.1.0
88killThread :: MonadIO m => ThreadId -> m ()
89killThread = liftIO . C.killThread
90{-# INLINABLE  killThread #-}
91
92-- | Unlifted version of 'C.forkOn'.
93--
94-- @since 0.1.1.0
95forkOn :: MonadUnliftIO m => Int -> m () -> m ThreadId
96forkOn i m = withRunInIO $ \run -> C.forkOn i $ run m
97{-# INLINABLE forkOn #-}
98
99-- | Unlifted version of 'C.forkOnWithUnmask'.
100--
101-- @since 0.1.1.0
102forkOnWithUnmask :: MonadUnliftIO m => Int -> ((forall a. m a -> m a) -> m ()) -> m ThreadId
103forkOnWithUnmask i m =
104  withRunInIO $ \run -> C.forkOnWithUnmask i $ \unmask -> run $ m $ liftIO . unmask . run
105{-# INLINABLE forkOnWithUnmask #-}
106
107-- | Lifted version of 'C.getNumCapabilities'.
108--
109-- @since 0.1.1.0
110getNumCapabilities :: MonadIO m => m Int
111getNumCapabilities = liftIO C.getNumCapabilities
112{-# INLINABLE getNumCapabilities #-}
113
114-- | Lifted version of 'C.setNumCapabilities'.
115--
116-- @since 0.1.1.0
117setNumCapabilities :: MonadIO m => Int -> m ()
118setNumCapabilities = liftIO . C.setNumCapabilities
119{-# INLINABLE setNumCapabilities #-}
120
121-- | Lifted version of 'C.threadCapability'.
122--
123-- @since 0.1.1.0
124threadCapability :: MonadIO m => ThreadId -> m (Int, Bool)
125threadCapability = liftIO . C.threadCapability
126{-# INLINABLE threadCapability #-}
127
128-- | Lifted version of 'C.yield'.
129--
130-- @since 0.1.1.0
131yield :: MonadIO m => m ()
132yield = liftIO C.yield
133{-# INLINABLE yield #-}
134
135-- | Lifted version of 'C.threadDelay'.
136--
137-- @since 0.1.1.0
138threadDelay :: MonadIO m => Int -> m ()
139threadDelay = liftIO .  C.threadDelay
140{-# INLINABLE threadDelay #-}
141
142-- | Lifted version of 'C.threadWaitRead'.
143--
144-- @since 0.1.1.0
145threadWaitRead :: MonadIO m => Fd -> m ()
146threadWaitRead = liftIO . C.threadWaitRead
147{-# INLINABLE threadWaitRead #-}
148
149-- | Lifted version of 'C.threadWaitWrite'.
150--
151-- @since 0.1.1.0
152threadWaitWrite :: MonadIO m => Fd -> m ()
153threadWaitWrite = liftIO . C.threadWaitWrite
154{-# INLINABLE threadWaitWrite #-}
155
156-- | Unflifted version of 'C.forkOS'.
157--
158-- @since 0.1.1.0
159forkOS :: MonadUnliftIO m => m () -> m ThreadId
160forkOS m = withRunInIO $ \run -> C.forkOS $ run m
161{-# INLINABLE forkOS #-}
162
163-- | Lifted version of 'C.isCurrentThreadBound'.
164--
165-- @since 0.1.1.0
166isCurrentThreadBound :: MonadIO m => m Bool
167isCurrentThreadBound = liftIO C.isCurrentThreadBound
168{-# INLINABLE isCurrentThreadBound #-}
169
170-- | Unlifted version of 'C.runInBoundThread'.
171--
172-- @since 0.1.1.0
173runInBoundThread :: MonadUnliftIO m => m a -> m a
174runInBoundThread m = withRunInIO $ \run -> C.runInBoundThread $ run m
175{-# INLINABLE runInBoundThread #-}
176
177-- | Unlifted version of 'C.runInUnboundThread'.
178--
179-- @since 0.1.1.0
180runInUnboundThread :: MonadUnliftIO m => m a -> m a
181runInUnboundThread m = withRunInIO $ \run -> C.runInUnboundThread $ run m
182{-# INLINABLE runInUnboundThread #-}
183
184-- | Lifted version of 'C.mkWeakThreadId'.
185--
186-- @since 0.1.1.0
187mkWeakThreadId :: MonadIO m => ThreadId -> m (Weak ThreadId)
188mkWeakThreadId = liftIO . C.mkWeakThreadId
189{-# INLINABLE mkWeakThreadId #-}
190