{- | Copyright : Will Thompson, Iñaki García Etxebarria and Jonas Platte License : LGPL-2.1 Maintainer : Iñaki García Etxebarria (garetxe@gmail.com) The 'GI.GLib.Structs.Thread.Thread' struct represents a running thread. This struct is returned by @/g_thread_new()/@ or @/g_thread_try_new()/@. You can obtain the 'GI.GLib.Structs.Thread.Thread' struct representing the current thread by calling 'GI.GLib.Functions.threadSelf'. GThread is refcounted, see 'GI.GLib.Structs.Thread.threadRef' and 'GI.GLib.Structs.Thread.threadUnref'. The thread represented by it holds a reference while it is running, and 'GI.GLib.Structs.Thread.threadJoin' consumes the reference that it is given, so it is normally not necessary to manage GThread references explicitly. The structure is opaque -- none of its fields may be directly accessed. -} #define ENABLE_OVERLOADING (MIN_VERSION_haskell_gi_overloading(1,0,0) \ && !defined(__HADDOCK_VERSION__)) module GI.GLib.Structs.Thread ( -- * Exported types Thread(..) , noThread , -- * Methods -- ** errorQuark #method:errorQuark# threadErrorQuark , -- ** exit #method:exit# threadExit , -- ** join #method:join# #if ENABLE_OVERLOADING ThreadJoinMethodInfo , #endif threadJoin , -- ** ref #method:ref# #if ENABLE_OVERLOADING ThreadRefMethodInfo , #endif threadRef , -- ** self #method:self# threadSelf , -- ** unref #method:unref# #if ENABLE_OVERLOADING ThreadUnrefMethodInfo , #endif threadUnref , -- ** yield #method:yield# threadYield , ) where import Data.GI.Base.ShortPrelude import qualified Data.GI.Base.ShortPrelude as SP import qualified Data.GI.Base.Overloading as O import qualified Prelude as P import qualified Data.GI.Base.Attributes as GI.Attributes import qualified Data.GI.Base.ManagedPtr as B.ManagedPtr import qualified Data.GI.Base.GError as B.GError import qualified Data.GI.Base.GVariant as B.GVariant import qualified Data.GI.Base.GValue as B.GValue import qualified Data.GI.Base.GParamSpec as B.GParamSpec import qualified Data.GI.Base.CallStack as B.CallStack import qualified Data.Text as T import qualified Data.ByteString.Char8 as B import qualified Data.Map as Map import qualified Foreign.Ptr as FP -- | Memory-managed wrapper type. newtype Thread = Thread (ManagedPtr Thread) foreign import ccall "g_thread_get_type" c_g_thread_get_type :: IO GType instance BoxedObject Thread where boxedType _ = c_g_thread_get_type -- | A convenience alias for `Nothing` :: `Maybe` `Thread`. noThread :: Maybe Thread noThread = Nothing #if ENABLE_OVERLOADING instance O.HasAttributeList Thread type instance O.AttributeList Thread = ThreadAttributeList type ThreadAttributeList = ('[ ] :: [(Symbol, *)]) #endif -- method Thread::join -- method type : OrdinaryMethod -- Args : [Arg {argCName = "thread", argType = TInterface (Name {namespace = "GLib", name = "Thread"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a #GThread", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing}] -- Lengths : [] -- returnType : Just (TBasicType TPtr) -- throws : False -- Skip return : False foreign import ccall "g_thread_join" g_thread_join :: Ptr Thread -> -- thread : TInterface (Name {namespace = "GLib", name = "Thread"}) IO (Ptr ()) {- | Waits until /@thread@/ finishes, i.e. the function /@func@/, as given to @/g_thread_new()/@, returns or 'GI.GLib.Functions.threadExit' is called. If /@thread@/ has already terminated, then 'GI.GLib.Structs.Thread.threadJoin' returns immediately. Any thread can wait for any other thread by calling 'GI.GLib.Structs.Thread.threadJoin', not just its \'creator\'. Calling 'GI.GLib.Structs.Thread.threadJoin' from multiple threads for the same /@thread@/ leads to undefined behaviour. The value returned by /@func@/ or given to 'GI.GLib.Functions.threadExit' is returned by this function. 'GI.GLib.Structs.Thread.threadJoin' consumes the reference to the passed-in /@thread@/. This will usually cause the 'GI.GLib.Structs.Thread.Thread' struct and associated resources to be freed. Use 'GI.GLib.Structs.Thread.threadRef' to obtain an extra reference if you want to keep the GThread alive beyond the 'GI.GLib.Structs.Thread.threadJoin' call. -} threadJoin :: (B.CallStack.HasCallStack, MonadIO m) => Thread {- ^ /@thread@/: a 'GI.GLib.Structs.Thread.Thread' -} -> m (Ptr ()) {- ^ __Returns:__ the return value of the thread -} threadJoin thread = liftIO $ do thread' <- unsafeManagedPtrGetPtr thread result <- g_thread_join thread' touchManagedPtr thread return result #if ENABLE_OVERLOADING data ThreadJoinMethodInfo instance (signature ~ (m (Ptr ())), MonadIO m) => O.MethodInfo ThreadJoinMethodInfo Thread signature where overloadedMethod _ = threadJoin #endif -- method Thread::ref -- method type : OrdinaryMethod -- Args : [Arg {argCName = "thread", argType = TInterface (Name {namespace = "GLib", name = "Thread"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a #GThread", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing}] -- Lengths : [] -- returnType : Just (TInterface (Name {namespace = "GLib", name = "Thread"})) -- throws : False -- Skip return : False foreign import ccall "g_thread_ref" g_thread_ref :: Ptr Thread -> -- thread : TInterface (Name {namespace = "GLib", name = "Thread"}) IO (Ptr Thread) {- | Increase the reference count on /@thread@/. /Since: 2.32/ -} threadRef :: (B.CallStack.HasCallStack, MonadIO m) => Thread {- ^ /@thread@/: a 'GI.GLib.Structs.Thread.Thread' -} -> m Thread {- ^ __Returns:__ a new reference to /@thread@/ -} threadRef thread = liftIO $ do thread' <- unsafeManagedPtrGetPtr thread result <- g_thread_ref thread' checkUnexpectedReturnNULL "threadRef" result result' <- (wrapBoxed Thread) result touchManagedPtr thread return result' #if ENABLE_OVERLOADING data ThreadRefMethodInfo instance (signature ~ (m Thread), MonadIO m) => O.MethodInfo ThreadRefMethodInfo Thread signature where overloadedMethod _ = threadRef #endif -- method Thread::unref -- method type : OrdinaryMethod -- Args : [Arg {argCName = "thread", argType = TInterface (Name {namespace = "GLib", name = "Thread"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a #GThread", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing}] -- Lengths : [] -- returnType : Nothing -- throws : False -- Skip return : False foreign import ccall "g_thread_unref" g_thread_unref :: Ptr Thread -> -- thread : TInterface (Name {namespace = "GLib", name = "Thread"}) IO () {- | Decrease the reference count on /@thread@/, possibly freeing all resources associated with it. Note that each thread holds a reference to its 'GI.GLib.Structs.Thread.Thread' while it is running, so it is safe to drop your own reference to it if you don\'t need it anymore. /Since: 2.32/ -} threadUnref :: (B.CallStack.HasCallStack, MonadIO m) => Thread {- ^ /@thread@/: a 'GI.GLib.Structs.Thread.Thread' -} -> m () threadUnref thread = liftIO $ do thread' <- unsafeManagedPtrGetPtr thread g_thread_unref thread' touchManagedPtr thread return () #if ENABLE_OVERLOADING data ThreadUnrefMethodInfo instance (signature ~ (m ()), MonadIO m) => O.MethodInfo ThreadUnrefMethodInfo Thread signature where overloadedMethod _ = threadUnref #endif -- method Thread::error_quark -- method type : MemberFunction -- Args : [] -- Lengths : [] -- returnType : Just (TBasicType TUInt32) -- throws : False -- Skip return : False foreign import ccall "g_thread_error_quark" g_thread_error_quark :: IO Word32 {- | /No description available in the introspection data./ -} threadErrorQuark :: (B.CallStack.HasCallStack, MonadIO m) => m Word32 threadErrorQuark = liftIO $ do result <- g_thread_error_quark return result #if ENABLE_OVERLOADING #endif -- method Thread::exit -- method type : MemberFunction -- Args : [Arg {argCName = "retval", argType = TBasicType TPtr, direction = DirectionIn, mayBeNull = True, argDoc = Documentation {rawDocText = Just "the return value of this thread", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing}] -- Lengths : [] -- returnType : Nothing -- throws : False -- Skip return : False foreign import ccall "g_thread_exit" g_thread_exit :: Ptr () -> -- retval : TBasicType TPtr IO () {- | Terminates the current thread. If another thread is waiting for us using 'GI.GLib.Structs.Thread.threadJoin' then the waiting thread will be woken up and get /@retval@/ as the return value of 'GI.GLib.Structs.Thread.threadJoin'. Calling 'GI.GLib.Functions.threadExit' with a parameter /@retval@/ is equivalent to returning /@retval@/ from the function /@func@/, as given to @/g_thread_new()/@. You must only call 'GI.GLib.Functions.threadExit' from a thread that you created yourself with @/g_thread_new()/@ or related APIs. You must not call this function from a thread created with another threading library or or from within a 'GI.GLib.Structs.ThreadPool.ThreadPool'. -} threadExit :: (B.CallStack.HasCallStack, MonadIO m) => Ptr () {- ^ /@retval@/: the return value of this thread -} -> m () threadExit retval = liftIO $ do g_thread_exit retval return () #if ENABLE_OVERLOADING #endif -- method Thread::self -- method type : MemberFunction -- Args : [] -- Lengths : [] -- returnType : Just (TInterface (Name {namespace = "GLib", name = "Thread"})) -- throws : False -- Skip return : False foreign import ccall "g_thread_self" g_thread_self :: IO (Ptr Thread) {- | This function returns the 'GI.GLib.Structs.Thread.Thread' corresponding to the current thread. Note that this function does not increase the reference count of the returned struct. This function will return a 'GI.GLib.Structs.Thread.Thread' even for threads that were not created by GLib (i.e. those created by other threading APIs). This may be useful for thread identification purposes (i.e. comparisons) but you must not use GLib functions (such as 'GI.GLib.Structs.Thread.threadJoin') on these threads. -} threadSelf :: (B.CallStack.HasCallStack, MonadIO m) => m Thread {- ^ __Returns:__ the 'GI.GLib.Structs.Thread.Thread' representing the current thread -} threadSelf = liftIO $ do result <- g_thread_self checkUnexpectedReturnNULL "threadSelf" result result' <- (newBoxed Thread) result return result' #if ENABLE_OVERLOADING #endif -- method Thread::yield -- method type : MemberFunction -- Args : [] -- Lengths : [] -- returnType : Nothing -- throws : False -- Skip return : False foreign import ccall "g_thread_yield" g_thread_yield :: IO () {- | Causes the calling thread to voluntarily relinquish the CPU, so that other threads can run. This function is often used as a method to make busy wait less evil. -} threadYield :: (B.CallStack.HasCallStack, MonadIO m) => m () threadYield = liftIO $ do g_thread_yield return () #if ENABLE_OVERLOADING #endif #if ENABLE_OVERLOADING type family ResolveThreadMethod (t :: Symbol) (o :: *) :: * where ResolveThreadMethod "join" o = ThreadJoinMethodInfo ResolveThreadMethod "ref" o = ThreadRefMethodInfo ResolveThreadMethod "unref" o = ThreadUnrefMethodInfo ResolveThreadMethod l o = O.MethodResolutionFailed l o instance (info ~ ResolveThreadMethod t Thread, O.MethodInfo info Thread p) => O.IsLabelProxy t (Thread -> p) where fromLabelProxy _ = O.overloadedMethod (O.MethodProxy :: O.MethodProxy info) #if MIN_VERSION_base(4,9,0) instance (info ~ ResolveThreadMethod t Thread, O.MethodInfo info Thread p) => O.IsLabel t (Thread -> p) where #if MIN_VERSION_base(4,10,0) fromLabel = O.overloadedMethod (O.MethodProxy :: O.MethodProxy info) #else fromLabel _ = O.overloadedMethod (O.MethodProxy :: O.MethodProxy info) #endif #endif #endif