    {-# LANGUAGE TypeApplications #-}

    -- | Copyright  : Will Thompson and Iñaki García Etxebarria
    -- License    : LGPL-2.1
    -- Maintainer : Iñaki García Etxebarria
    --
    -- The t'GI.GLib.Unions.Mutex.Mutex' struct is an opaque data structure to represent a mutex
    -- (mutual exclusion). It can be used to protect data against shared
    -- access.
    --
    -- Take for example the following function:
    --
    -- === /C code/
    -- >
    -- >  int
    -- >  give_me_next_number (void)
    -- >  {
    -- >    static int current_number = 0;
    -- >
    -- >    // now do a very complicated calculation to calculate the new
    -- >    // number, this might for example be a random number generator
    -- >    current_number = calc_next_number (current_number);
    -- >
    -- >    return current_number;
    -- >  }
    --
    -- It is easy to see that this won\'t work in a multi-threaded
    -- application. There current_number must be protected against shared
    -- access. A t'GI.GLib.Unions.Mutex.Mutex' can be used as a solution to this problem:
    --
    -- === /C code/
    -- >
    -- >  int
    -- >  give_me_next_number (void)
    -- >  {
    -- >    static GMutex mutex;
    -- >    static int current_number = 0;
    -- >    int ret_val;
    -- >
    -- >    g_mutex_lock (&mutex);
    -- >    ret_val = current_number = calc_next_number (current_number);
    -- >    g_mutex_unlock (&mutex);
    -- >
    -- >    return ret_val;
    -- >  }
    --
    -- Notice that the t'GI.GLib.Unions.Mutex.Mutex' is not initialised to any particular value.
    -- Its placement in static storage ensures that it will be initialised
    -- to all-zeros, which is appropriate.
    --
    -- If a t'GI.GLib.Unions.Mutex.Mutex' is placed in other contexts (eg: embedded in a struct)
    -- then it must be explicitly initialised using 'GI.GLib.Unions.Mutex.mutexInit'.
    --
    -- A t'GI.GLib.Unions.Mutex.Mutex' should only be accessed via g_mutex_ functions.

    #if !defined(__HADDOCK_VERSION__)
    #define ENABLE_OVERLOADING
    #endif

    module GI.GLib.Unions.Mutex
        (

    -- * Exported types
        Mutex(..)                               ,
        newZeroMutex                            ,

     -- * Methods
    -- |
    --
    --  === __Click to display all available methods, including inherited ones__
    -- ==== Methods
    -- [clear]("GI.GLib.Unions.Mutex#g:method:clear"), [init]("GI.GLib.Unions.Mutex#g:method:init"), [lock]("GI.GLib.Unions.Mutex#g:method:lock"), [trylock]("GI.GLib.Unions.Mutex#g:method:trylock"), [unlock]("GI.GLib.Unions.Mutex#g:method:unlock").
    --
    -- ==== Getters
    -- /None/.
    --
    -- ==== Setters
    -- /None/.

    #if defined(ENABLE_OVERLOADING)
        ResolveMutexMethod                      ,
    #endif

    -- ** clear #method:clear#

    #if defined(ENABLE_OVERLOADING)
        MutexClearMethodInfo                    ,
    #endif
        mutexClear                              ,

    -- ** init #method:init#

    #if defined(ENABLE_OVERLOADING)
        MutexInitMethodInfo                     ,
    #endif
        mutexInit                               ,

    -- ** lock #method:lock#

    #if defined(ENABLE_OVERLOADING)
        MutexLockMethodInfo                     ,
    #endif
        mutexLock                               ,

    -- ** trylock #method:trylock#

    #if defined(ENABLE_OVERLOADING)
        MutexTrylockMethodInfo                  ,
    #endif
        mutexTrylock                            ,

    -- ** unlock #method:unlock#

    #if defined(ENABLE_OVERLOADING)
        MutexUnlockMethodInfo                   ,
    #endif
        mutexUnlock                             ,

        ) 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.BasicTypes as B.Types
    import qualified Data.GI.Base.ManagedPtr as B.ManagedPtr
    import qualified Data.GI.Base.GArray as B.GArray
    import qualified Data.GI.Base.GClosure as B.GClosure
    import qualified Data.GI.Base.GError as B.GError
    import qualified Data.GI.Base.GHashTable as B.GHT
    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.GI.Base.Properties as B.Properties
    import qualified Data.GI.Base.Signals as B.Signals
    import qualified Control.Monad.IO.Class as MIO
    import qualified Data.Coerce as Coerce
    import qualified Data.Text as T
    import qualified Data.Kind as DK
    import qualified Data.ByteString.Char8 as B
    import qualified Data.Map as Map
    import qualified Foreign.Ptr as FP
    import qualified GHC.OverloadedLabels as OL
    import qualified GHC.Records as R
    import qualified Data.Word as DW
    import qualified Data.Int as DI
    import qualified System.Posix.Types as SPT
    import qualified Foreign.C.Types as FCT

    -- Workaround for https://gitlab.haskell.org/ghc/ghc/-/issues/23392
    #if MIN_VERSION_base(4,18,0)

    #else

    #endif

    -- | Memory-managed wrapper type.
    newtype Mutex = Mutex (SP.ManagedPtr Mutex)
        deriving (Mutex -> Mutex -> Bool
    (Mutex -> Mutex -> Bool) -> (Mutex -> Mutex -> Bool) -> Eq Mutex
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: Mutex -> Mutex -> Bool
    == :: Mutex -> Mutex -> Bool
    $c/= :: Mutex -> Mutex -> Bool
    /= :: Mutex -> Mutex -> Bool
    Eq)

    instance SP.ManagedPtrNewtype Mutex where
        toManagedPtr :: Mutex -> ManagedPtr Mutex
    toManagedPtr (Mutex ManagedPtr Mutex
    p) = ManagedPtr Mutex
    p

    instance BoxedPtr Mutex where
        boxedPtrCopy :: Mutex -> IO Mutex
    boxedPtrCopy = \Mutex
    p -> Mutex -> (Ptr Mutex -> IO Mutex) -> IO Mutex
    forall a c.
    (HasCallStack, ManagedPtrNewtype a) =>
    a -> (Ptr a -> IO c) -> IO c
    B.ManagedPtr.withManagedPtr Mutex
    p (Int -> Ptr Mutex -> IO (Ptr Mutex)
    forall a. (HasCallStack, CallocPtr a) => Int -> Ptr a -> IO (Ptr a)
    copyBytes Int
    8 (Ptr Mutex -> IO (Ptr Mutex))
    -> (Ptr Mutex -> IO Mutex) -> Ptr Mutex -> IO Mutex
    forall (m :: * -> *) a b c.
    Monad m =>
    (a -> m b) -> (b -> m c) -> a -> m c
    >=> (ManagedPtr Mutex -> Mutex) -> Ptr Mutex -> IO Mutex
    forall a.
    (HasCallStack, BoxedPtr a) =>
    (ManagedPtr a -> a) -> Ptr a -> IO a
    B.ManagedPtr.wrapPtr ManagedPtr Mutex -> Mutex
    Mutex)
        boxedPtrFree :: Mutex -> IO ()
    boxedPtrFree = \Mutex
    x -> Mutex -> (Ptr Mutex -> IO ()) -> IO ()
    forall a c.
    (HasCallStack, ManagedPtrNewtype a) =>
    a -> (Ptr a -> IO c) -> IO c
    SP.withManagedPtr Mutex
    x Ptr Mutex -> IO ()
    forall a. Ptr a -> IO ()
    SP.freeMem
    instance CallocPtr Mutex where
        boxedPtrCalloc :: IO (Ptr Mutex)
    boxedPtrCalloc = Int -> IO (Ptr Mutex)
    forall a. Int -> IO (Ptr a)
    callocBytes Int
    8

    -- | Construct a t'Mutex' struct initialized to zero.
    newZeroMutex :: MonadIO m => m Mutex
    newZeroMutex :: forall (m :: * -> *). MonadIO m => m Mutex
    newZeroMutex = IO Mutex -> m Mutex
    forall a. IO a -> m a
    forall (m :: * -> *) a. MonadIO m => IO a -> m a
    liftIO (IO Mutex -> m Mutex) -> IO Mutex -> m Mutex
    forall a b. (a -> b) -> a -> b
    $ IO (Ptr Mutex)
    forall a. CallocPtr a => IO (Ptr a)
    boxedPtrCalloc IO (Ptr Mutex) -> (Ptr Mutex -> IO Mutex) -> IO Mutex
    forall a b. IO a -> (a -> IO b) -> IO b
    forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
    >>= (ManagedPtr Mutex -> Mutex) -> Ptr Mutex -> IO Mutex
    forall a.
    (HasCallStack, BoxedPtr a) =>
    (ManagedPtr a -> a) -> Ptr a -> IO a
    wrapPtr ManagedPtr Mutex -> Mutex
    Mutex

    instance tag ~ 'AttrSet => Constructible Mutex tag where
        new :: forall (m :: * -> *).
    MonadIO m =>
    (ManagedPtr Mutex -> Mutex) -> [AttrOp Mutex tag] -> m Mutex
    new ManagedPtr Mutex -> Mutex
    _ [AttrOp Mutex tag]
    attrs = do
            o <- m Mutex
    forall (m :: * -> *). MonadIO m => m Mutex
    newZeroMutex
            GI.Attributes.set o attrs
            return o

    #if defined(ENABLE_OVERLOADING)
    instance O.HasAttributeList Mutex
    type instance O.AttributeList Mutex = MutexAttributeList
    type MutexAttributeList = ('[ ] :: [(Symbol, DK.Type)])
    #endif

    -- method Mutex::clear
    -- method type : OrdinaryMethod
    -- Args: [ Arg
    --           { argCName = "mutex"
    --           , argType = TInterface Name { namespace = "GLib" , name = "Mutex" }
    --           , argCType = Just "GMutex*"
    --           , direction = DirectionIn
    --           , mayBeNull = False
    --           , argDoc =
    --               Documentation
    --                 { rawDocText = Just "an initialized #GMutex"
    --                 , sinceVersion = Nothing
    --                 }
    --           , argScope = ScopeTypeInvalid
    --           , argClosure = -1
    --           , argDestroy = -1
    --           , argCallerAllocates = False
    --           , argCallbackUserData = False
    --           , transfer = TransferNothing
    --           }
    --       ]
    -- Lengths: []
    -- returnType: Nothing
    -- throws : False
    -- Skip return : False

    foreign import ccall "g_mutex_clear" g_mutex_clear ::
        Ptr Mutex ->                            -- mutex : TInterface (Name {namespace = "GLib", name = "Mutex"})
        IO ()

    -- | Frees the resources allocated to a mutex with 'GI.GLib.Unions.Mutex.mutexInit'.
    --
    -- This function should not be used with a t'GI.GLib.Unions.Mutex.Mutex' that has been
    -- statically allocated.
    --
    -- Calling 'GI.GLib.Unions.Mutex.mutexClear' on a locked mutex leads to undefined
    -- behaviour.
    --
    -- /Since: 2.32/
    mutexClear ::
        (B.CallStack.HasCallStack, MonadIO m) =>
        Mutex
        -- ^ /@mutex@/: an initialized t'GI.GLib.Unions.Mutex.Mutex'
        -> m ()
    mutexClear :: forall (m :: * -> *). (HasCallStack, MonadIO m) => Mutex -> m ()
    mutexClear Mutex
    mutex = IO () -> m ()
    forall a. IO a -> m a
    forall (m :: * -> *) a. MonadIO m => IO a -> m a
    liftIO (IO () -> m ()) -> IO () -> m ()
    forall a b. (a -> b) -> a -> b
    $ do
        mutex' <- Mutex -> IO (Ptr Mutex)
    forall a. (HasCallStack, ManagedPtrNewtype a) => a -> IO (Ptr a)
    unsafeManagedPtrGetPtr Mutex
    mutex
        g_mutex_clear mutex'
        touchManagedPtr mutex
        return ()

    #if defined(ENABLE_OVERLOADING)
    data MutexClearMethodInfo
    instance (signature ~ (m ()), MonadIO m) => O.OverloadedMethod MutexClearMethodInfo Mutex signature where
        overloadedMethod = mutexClear

    instance O.OverloadedMethodInfo MutexClearMethodInfo Mutex where
        overloadedMethodInfo = P.Just (O.ResolvedSymbolInfo {
            O.resolvedSymbolName = "GI.GLib.Unions.Mutex.mutexClear",
            O.resolvedSymbolURL = "https://hackage.haskell.org/package/gi-glib-2.0.30/docs/GI-GLib-Unions-Mutex.html#v:mutexClear"
            })

    #endif

    -- method Mutex::init
    -- method type : OrdinaryMethod
    -- Args: [ Arg
    --           { argCName = "mutex"
    --           , argType = TInterface Name { namespace = "GLib" , name = "Mutex" }
    --           , argCType = Just "GMutex*"
    --           , direction = DirectionIn
    --           , mayBeNull = False
    --           , argDoc =
    --               Documentation
    --                 { rawDocText = Just "an uninitialized #GMutex"
    --                 , sinceVersion = Nothing
    --                 }
    --           , argScope = ScopeTypeInvalid
    --           , argClosure = -1
    --           , argDestroy = -1
    --           , argCallerAllocates = False
    --           , argCallbackUserData = False
    --           , transfer = TransferNothing
    --           }
    --       ]
    -- Lengths: []
    -- returnType: Nothing
    -- throws : False
    -- Skip return : False

    foreign import ccall "g_mutex_init" g_mutex_init ::
        Ptr Mutex ->                            -- mutex : TInterface (Name {namespace = "GLib", name = "Mutex"})
        IO ()

    -- | Initializes a t'GI.GLib.Unions.Mutex.Mutex' so that it can be used.
    --
    -- This function is useful to initialize a mutex that has been
    -- allocated on the stack, or as part of a larger structure.
    -- It is not necessary to initialize a mutex that has been
    -- statically allocated.
    --
    --
    -- === /C code/
    -- >
    -- >  typedef struct {
    -- >    GMutex m;
    -- >    ...
    -- >  } Blob;
    -- >
    -- >Blob *b;
    -- >
    -- >b = g_new (Blob, 1);
    -- >g_mutex_init (&b->m);
    --
    --
    -- To undo the effect of 'GI.GLib.Unions.Mutex.mutexInit' when a mutex is no longer
    -- needed, use 'GI.GLib.Unions.Mutex.mutexClear'.
    --
    -- Calling 'GI.GLib.Unions.Mutex.mutexInit' on an already initialized t'GI.GLib.Unions.Mutex.Mutex' leads
    -- to undefined behaviour.
    --
    -- /Since: 2.32/
    mutexInit ::
        (B.CallStack.HasCallStack, MonadIO m) =>
        Mutex
        -- ^ /@mutex@/: an uninitialized t'GI.GLib.Unions.Mutex.Mutex'
        -> m ()
    mutexInit :: forall (m :: * -> *). (HasCallStack, MonadIO m) => Mutex -> m ()
    mutexInit Mutex
    mutex = IO () -> m ()
    forall a. IO a -> m a
    forall (m :: * -> *) a. MonadIO m => IO a -> m a
    liftIO (IO () -> m ()) -> IO () -> m ()
    forall a b. (a -> b) -> a -> b
    $ do
        mutex' <- Mutex -> IO (Ptr Mutex)
    forall a. (HasCallStack, ManagedPtrNewtype a) => a -> IO (Ptr a)
    unsafeManagedPtrGetPtr Mutex
    mutex
        g_mutex_init mutex'
        touchManagedPtr mutex
        return ()

    #if defined(ENABLE_OVERLOADING)
    data MutexInitMethodInfo
    instance (signature ~ (m ()), MonadIO m) => O.OverloadedMethod MutexInitMethodInfo Mutex signature where
        overloadedMethod = mutexInit

    instance O.OverloadedMethodInfo MutexInitMethodInfo Mutex where
        overloadedMethodInfo = P.Just (O.ResolvedSymbolInfo {
            O.resolvedSymbolName = "GI.GLib.Unions.Mutex.mutexInit",
            O.resolvedSymbolURL = "https://hackage.haskell.org/package/gi-glib-2.0.30/docs/GI-GLib-Unions-Mutex.html#v:mutexInit"
            })

    #endif

    -- method Mutex::lock
    -- method type : OrdinaryMethod
    -- Args: [ Arg
    --           { argCName = "mutex"
    --           , argType = TInterface Name { namespace = "GLib" , name = "Mutex" }
    --           , argCType = Just "GMutex*"
    --           , direction = DirectionIn
    --           , mayBeNull = False
    --           , argDoc =
    --               Documentation
    --                 { rawDocText = Just "a #GMutex" , sinceVersion = Nothing }
    --           , argScope = ScopeTypeInvalid
    --           , argClosure = -1
    --           , argDestroy = -1
    --           , argCallerAllocates = False
    --           , argCallbackUserData = False
    --           , transfer = TransferNothing
    --           }
    --       ]
    -- Lengths: []
    -- returnType: Nothing
    -- throws : False
    -- Skip return : False

    foreign import ccall "g_mutex_lock" g_mutex_lock ::
        Ptr Mutex ->                            -- mutex : TInterface (Name {namespace = "GLib", name = "Mutex"})
        IO ()

    -- | Locks /@mutex@/. If /@mutex@/ is already locked by another thread, the
    -- current thread will block until /@mutex@/ is unlocked by the other
    -- thread.
    --
    -- t'GI.GLib.Unions.Mutex.Mutex' is neither guaranteed to be recursive nor to be
    -- non-recursive.  As such, calling 'GI.GLib.Unions.Mutex.mutexLock' on a t'GI.GLib.Unions.Mutex.Mutex' that has
    -- already been locked by the same thread results in undefined behaviour
    -- (including but not limited to deadlocks).
    mutexLock ::
        (B.CallStack.HasCallStack, MonadIO m) =>
        Mutex
        -- ^ /@mutex@/: a t'GI.GLib.Unions.Mutex.Mutex'
        -> m ()
    mutexLock :: forall (m :: * -> *). (HasCallStack, MonadIO m) => Mutex -> m ()
    mutexLock Mutex
    mutex = IO () -> m ()
    forall a. IO a -> m a
    forall (m :: * -> *) a. MonadIO m => IO a -> m a
    liftIO (IO () -> m ()) -> IO () -> m ()
    forall a b. (a -> b) -> a -> b
    $ do
        mutex' <- Mutex -> IO (Ptr Mutex)
    forall a. (HasCallStack, ManagedPtrNewtype a) => a -> IO (Ptr a)
    unsafeManagedPtrGetPtr Mutex
    mutex
        g_mutex_lock mutex'
        touchManagedPtr mutex
        return ()

    #if defined(ENABLE_OVERLOADING)
    data MutexLockMethodInfo
    instance (signature ~ (m ()), MonadIO m) => O.OverloadedMethod MutexLockMethodInfo Mutex signature where
        overloadedMethod = mutexLock

    instance O.OverloadedMethodInfo MutexLockMethodInfo Mutex where
        overloadedMethodInfo = P.Just (O.ResolvedSymbolInfo {
            O.resolvedSymbolName = "GI.GLib.Unions.Mutex.mutexLock",
            O.resolvedSymbolURL = "https://hackage.haskell.org/package/gi-glib-2.0.30/docs/GI-GLib-Unions-Mutex.html#v:mutexLock"
            })

    #endif

    -- method Mutex::trylock
    -- method type : OrdinaryMethod
    -- Args: [ Arg
    --           { argCName = "mutex"
    --           , argType = TInterface Name { namespace = "GLib" , name = "Mutex" }
    --           , argCType = Just "GMutex*"
    --           , direction = DirectionIn
    --           , mayBeNull = False
    --           , argDoc =
    --               Documentation
    --                 { rawDocText = Just "a #GMutex" , sinceVersion = Nothing }
    --           , argScope = ScopeTypeInvalid
    --           , argClosure = -1
    --           , argDestroy = -1
    --           , argCallerAllocates = False
    --           , argCallbackUserData = False
    --           , transfer = TransferNothing
    --           }
    --       ]
    -- Lengths: []
    -- returnType: Just (TBasicType TBoolean)
    -- throws : False
    -- Skip return : False

    foreign import ccall "g_mutex_trylock" g_mutex_trylock ::
        Ptr Mutex ->                            -- mutex : TInterface (Name {namespace = "GLib", name = "Mutex"})
        IO CInt

    -- | Tries to lock /@mutex@/. If /@mutex@/ is already locked by another thread,
    -- it immediately returns 'P.False'. Otherwise it locks /@mutex@/ and returns
    -- 'P.True'.
    --
    -- t'GI.GLib.Unions.Mutex.Mutex' is neither guaranteed to be recursive nor to be
    -- non-recursive.  As such, calling 'GI.GLib.Unions.Mutex.mutexLock' on a t'GI.GLib.Unions.Mutex.Mutex' that has
    -- already been locked by the same thread results in undefined behaviour
    -- (including but not limited to deadlocks or arbitrary return values).
    mutexTrylock ::
        (B.CallStack.HasCallStack, MonadIO m) =>
        Mutex
        -- ^ /@mutex@/: a t'GI.GLib.Unions.Mutex.Mutex'
        -> m Bool
        -- ^ __Returns:__ 'P.True' if /@mutex@/ could be locked
    mutexTrylock :: forall (m :: * -> *). (HasCallStack, MonadIO m) => Mutex -> m Bool
    mutexTrylock Mutex
    mutex = IO Bool -> m Bool
    forall a. IO a -> m a
    forall (m :: * -> *) a. MonadIO m => IO a -> m a
    liftIO (IO Bool -> m Bool) -> IO Bool -> m Bool
    forall a b. (a -> b) -> a -> b
    $ do
        mutex' <- Mutex -> IO (Ptr Mutex)
    forall a. (HasCallStack, ManagedPtrNewtype a) => a -> IO (Ptr a)
    unsafeManagedPtrGetPtr Mutex
    mutex
        result <- g_mutex_trylock mutex'
        let result' = (CInt -> CInt -> Bool
    forall a. Eq a => a -> a -> Bool
    /= CInt
    0) CInt
    result
        touchManagedPtr mutex
        return result'

    #if defined(ENABLE_OVERLOADING)
    data MutexTrylockMethodInfo
    instance (signature ~ (m Bool), MonadIO m) => O.OverloadedMethod MutexTrylockMethodInfo Mutex signature where
        overloadedMethod = mutexTrylock

    instance O.OverloadedMethodInfo MutexTrylockMethodInfo Mutex where
        overloadedMethodInfo = P.Just (O.ResolvedSymbolInfo {
            O.resolvedSymbolName = "GI.GLib.Unions.Mutex.mutexTrylock",
            O.resolvedSymbolURL = "https://hackage.haskell.org/package/gi-glib-2.0.30/docs/GI-GLib-Unions-Mutex.html#v:mutexTrylock"
            })

    #endif

    -- method Mutex::unlock
    -- method type : OrdinaryMethod
    -- Args: [ Arg
    --           { argCName = "mutex"
    --           , argType = TInterface Name { namespace = "GLib" , name = "Mutex" }
    --           , argCType = Just "GMutex*"
    --           , direction = DirectionIn
    --           , mayBeNull = False
    --           , argDoc =
    --               Documentation
    --                 { rawDocText = Just "a #GMutex" , sinceVersion = Nothing }
    --           , argScope = ScopeTypeInvalid
    --           , argClosure = -1
    --           , argDestroy = -1
    --           , argCallerAllocates = False
    --           , argCallbackUserData = False
    --           , transfer = TransferNothing
    --           }
    --       ]
    -- Lengths: []
    -- returnType: Nothing
    -- throws : False
    -- Skip return : False

    foreign import ccall "g_mutex_unlock" g_mutex_unlock ::
        Ptr Mutex ->                            -- mutex : TInterface (Name {namespace = "GLib", name = "Mutex"})
        IO ()

    -- | Unlocks /@mutex@/. If another thread is blocked in a 'GI.GLib.Unions.Mutex.mutexLock'
    -- call for /@mutex@/, it will become unblocked and can lock /@mutex@/ itself.
    --
    -- Calling 'GI.GLib.Unions.Mutex.mutexUnlock' on a mutex that is not locked by the
    -- current thread leads to undefined behaviour.
    mutexUnlock ::
        (B.CallStack.HasCallStack, MonadIO m) =>
        Mutex
        -- ^ /@mutex@/: a t'GI.GLib.Unions.Mutex.Mutex'
        -> m ()
    mutexUnlock :: forall (m :: * -> *). (HasCallStack, MonadIO m) => Mutex -> m ()
    mutexUnlock Mutex
    mutex = IO () -> m ()
    forall a. IO a -> m a
    forall (m :: * -> *) a. MonadIO m => IO a -> m a
    liftIO (IO () -> m ()) -> IO () -> m ()
    forall a b. (a -> b) -> a -> b
    $ do
        mutex' <- Mutex -> IO (Ptr Mutex)
    forall a. (HasCallStack, ManagedPtrNewtype a) => a -> IO (Ptr a)
    unsafeManagedPtrGetPtr Mutex
    mutex
        g_mutex_unlock mutex'
        touchManagedPtr mutex
        return ()

    #if defined(ENABLE_OVERLOADING)
    data MutexUnlockMethodInfo
    instance (signature ~ (m ()), MonadIO m) => O.OverloadedMethod MutexUnlockMethodInfo Mutex signature where
        overloadedMethod = mutexUnlock

    instance O.OverloadedMethodInfo MutexUnlockMethodInfo Mutex where
        overloadedMethodInfo = P.Just (O.ResolvedSymbolInfo {
            O.resolvedSymbolName = "GI.GLib.Unions.Mutex.mutexUnlock",
            O.resolvedSymbolURL = "https://hackage.haskell.org/package/gi-glib-2.0.30/docs/GI-GLib-Unions-Mutex.html#v:mutexUnlock"
            })

    #endif

    #if defined(ENABLE_OVERLOADING)
    type family ResolveMutexMethod (t :: Symbol) (o :: DK.Type) :: DK.Type where
        ResolveMutexMethod "clear" o = MutexClearMethodInfo
        ResolveMutexMethod "init" o = MutexInitMethodInfo
        ResolveMutexMethod "lock" o = MutexLockMethodInfo
        ResolveMutexMethod "trylock" o = MutexTrylockMethodInfo
        ResolveMutexMethod "unlock" o = MutexUnlockMethodInfo
        ResolveMutexMethod l o = O.MethodResolutionFailed l o

    instance (info ~ ResolveMutexMethod t Mutex, O.OverloadedMethod info Mutex p) => OL.IsLabel t (Mutex -> p) where
    #if MIN_VERSION_base(4,10,0)
        fromLabel = O.overloadedMethod @info
    #else
        fromLabel _ = O.overloadedMethod @info
    #endif

    #if MIN_VERSION_base(4,13,0)
    instance (info ~ ResolveMutexMethod t Mutex, O.OverloadedMethod info Mutex p, R.HasField t Mutex p) => R.HasField t Mutex p where
        getField = O.overloadedMethod @info

    #endif

    instance (info ~ ResolveMutexMethod t Mutex, O.OverloadedMethodInfo info Mutex) => OL.IsLabel t (O.MethodProxy info Mutex) where
    #if MIN_VERSION_base(4,10,0)
        fromLabel = O.MethodProxy
    #else
        fromLabel _ = O.MethodProxy
    #endif

    #endif