{- |
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 GRWLock struct is an opaque data structure to represent a
reader-writer lock. It is similar to a 'GI.GLib.Unions.Mutex.Mutex' in that it allows
multiple threads to coordinate access to a shared resource.

The difference to a mutex is that a reader-writer lock discriminates
between read-only (\'reader\') and full (\'writer\') access. While only
one thread at a time is allowed write access (by holding the \'writer\'
lock via 'GI.GLib.Structs.RWLock.rWLockWriterLock'), multiple threads can gain
simultaneous read-only access (by holding the \'reader\' lock via
'GI.GLib.Structs.RWLock.rWLockReaderLock').

It is unspecified whether readers or writers have priority in acquiring the
lock when a reader already holds the lock and a writer is queued to acquire
it.

Here is an example for an array with access functions:

=== /C code/
>
>  GRWLock lock;
>  GPtrArray *array;
>
>  gpointer
>  my_array_get (guint index)
>  {
>    gpointer retval = NULL;
>
>    if (!array)
>      return NULL;
>
>    g_rw_lock_reader_lock (&lock);
>    if (index < array->len)
>      retval = g_ptr_array_index (array, index);
>    g_rw_lock_reader_unlock (&lock);
>
>    return retval;
>  }
>
>  void
>  my_array_set (guint index, gpointer data)
>  {
>    g_rw_lock_writer_lock (&lock);
>
>    if (!array)
>      array = g_ptr_array_new ();
>
>    if (index >= array->len)
>      g_ptr_array_set_size (array, index+1);
>    g_ptr_array_index (array, index) = data;
>
>    g_rw_lock_writer_unlock (&lock);
>  }
> 

This example shows an array which can be accessed by many readers
(the @/my_array_get()/@ function) simultaneously, whereas the writers
(the @/my_array_set()/@ function) will only be allowed one at a time
and only if no readers currently access the array. This is because
of the potentially dangerous resizing of the array. Using these
functions is fully multi-thread safe now.

If a 'GI.GLib.Structs.RWLock.RWLock' is allocated in static storage then it can be used
without initialisation.  Otherwise, you should call
'GI.GLib.Structs.RWLock.rWLockInit' on it and 'GI.GLib.Structs.RWLock.rWLockClear' when done.

A GRWLock should only be accessed with the g_rw_lock_ functions.

/Since: 2.32/
-}

#define ENABLE_OVERLOADING \
       (!defined(__HADDOCK_VERSION__))

module GI.GLib.Structs.RWLock
    ( 

-- * Exported types
    RWLock(..)                              ,
    newZeroRWLock                           ,
    noRWLock                                ,


 -- * Methods
-- ** clear #method:clear#

#if ENABLE_OVERLOADING
    RWLockClearMethodInfo                   ,
#endif
    rWLockClear                             ,


-- ** init #method:init#

#if ENABLE_OVERLOADING
    RWLockInitMethodInfo                    ,
#endif
    rWLockInit                              ,


-- ** readerLock #method:readerLock#

#if ENABLE_OVERLOADING
    RWLockReaderLockMethodInfo              ,
#endif
    rWLockReaderLock                        ,


-- ** readerTrylock #method:readerTrylock#

#if ENABLE_OVERLOADING
    RWLockReaderTrylockMethodInfo           ,
#endif
    rWLockReaderTrylock                     ,


-- ** readerUnlock #method:readerUnlock#

#if ENABLE_OVERLOADING
    RWLockReaderUnlockMethodInfo            ,
#endif
    rWLockReaderUnlock                      ,


-- ** writerLock #method:writerLock#

#if ENABLE_OVERLOADING
    RWLockWriterLockMethodInfo              ,
#endif
    rWLockWriterLock                        ,


-- ** writerTrylock #method:writerTrylock#

#if ENABLE_OVERLOADING
    RWLockWriterTrylockMethodInfo           ,
#endif
    rWLockWriterTrylock                     ,


-- ** writerUnlock #method:writerUnlock#

#if ENABLE_OVERLOADING
    RWLockWriterUnlockMethodInfo            ,
#endif
    rWLockWriterUnlock                      ,




    ) 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 RWLock = RWLock (ManagedPtr RWLock)
instance WrappedPtr RWLock where
    wrappedPtrCalloc :: IO (Ptr RWLock)
wrappedPtrCalloc = Int -> IO (Ptr RWLock)
forall a. Int -> IO (Ptr a)
callocBytes 16
    wrappedPtrCopy :: RWLock -> IO RWLock
wrappedPtrCopy = \p :: RWLock
p -> RWLock -> (Ptr RWLock -> IO RWLock) -> IO RWLock
forall a c.
(HasCallStack, ManagedPtrNewtype a) =>
a -> (Ptr a -> IO c) -> IO c
withManagedPtr RWLock
p (Int -> Ptr RWLock -> IO (Ptr RWLock)
forall a. WrappedPtr a => Int -> Ptr a -> IO (Ptr a)
copyBytes 16 (Ptr RWLock -> IO (Ptr RWLock))
-> (Ptr RWLock -> IO RWLock) -> Ptr RWLock -> IO RWLock
forall (m :: * -> *) a b c.
Monad m =>
(a -> m b) -> (b -> m c) -> a -> m c
>=> (ManagedPtr RWLock -> RWLock) -> Ptr RWLock -> IO RWLock
forall a.
(HasCallStack, WrappedPtr a) =>
(ManagedPtr a -> a) -> Ptr a -> IO a
wrapPtr ManagedPtr RWLock -> RWLock
RWLock)
    wrappedPtrFree :: Maybe (FunPtr (Ptr RWLock -> IO ()))
wrappedPtrFree = FunPtr (Ptr RWLock -> IO ())
-> Maybe (FunPtr (Ptr RWLock -> IO ()))
forall a. a -> Maybe a
Just FunPtr (Ptr RWLock -> IO ())
forall a. FunPtr (Ptr a -> IO ())
ptr_to_g_free

-- | Construct a `RWLock` struct initialized to zero.
newZeroRWLock :: MonadIO m => m RWLock
newZeroRWLock :: m RWLock
newZeroRWLock = IO RWLock -> m RWLock
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO RWLock -> m RWLock) -> IO RWLock -> m RWLock
forall a b. (a -> b) -> a -> b
$ IO (Ptr RWLock)
forall a. WrappedPtr a => IO (Ptr a)
wrappedPtrCalloc IO (Ptr RWLock) -> (Ptr RWLock -> IO RWLock) -> IO RWLock
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (ManagedPtr RWLock -> RWLock) -> Ptr RWLock -> IO RWLock
forall a.
(HasCallStack, WrappedPtr a) =>
(ManagedPtr a -> a) -> Ptr a -> IO a
wrapPtr ManagedPtr RWLock -> RWLock
RWLock

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


-- | A convenience alias for `Nothing` :: `Maybe` `RWLock`.
noRWLock :: Maybe RWLock
noRWLock :: Maybe RWLock
noRWLock = Maybe RWLock
forall a. Maybe a
Nothing


#if ENABLE_OVERLOADING
instance O.HasAttributeList RWLock
type instance O.AttributeList RWLock = RWLockAttributeList
type RWLockAttributeList = ('[ ] :: [(Symbol, *)])
#endif

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

foreign import ccall "g_rw_lock_clear" g_rw_lock_clear :: 
    Ptr RWLock ->                           -- rw_lock : TInterface (Name {namespace = "GLib", name = "RWLock"})
    IO ()

{- |
Frees the resources allocated to a lock with 'GI.GLib.Structs.RWLock.rWLockInit'.

This function should not be used with a 'GI.GLib.Structs.RWLock.RWLock' that has been
statically allocated.

Calling 'GI.GLib.Structs.RWLock.rWLockClear' when any thread holds the lock
leads to undefined behaviour.

Sine: 2.32
-}
rWLockClear ::
    (B.CallStack.HasCallStack, MonadIO m) =>
    RWLock
    {- ^ /@rwLock@/: an initialized 'GI.GLib.Structs.RWLock.RWLock' -}
    -> m ()
rWLockClear :: RWLock -> m ()
rWLockClear rwLock :: RWLock
rwLock = IO () -> m ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> m ()) -> IO () -> m ()
forall a b. (a -> b) -> a -> b
$ do
    Ptr RWLock
rwLock' <- RWLock -> IO (Ptr RWLock)
forall a. (HasCallStack, ManagedPtrNewtype a) => a -> IO (Ptr a)
unsafeManagedPtrGetPtr RWLock
rwLock
    Ptr RWLock -> IO ()
g_rw_lock_clear Ptr RWLock
rwLock'
    RWLock -> IO ()
forall a. ManagedPtrNewtype a => a -> IO ()
touchManagedPtr RWLock
rwLock
    () -> IO ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()

#if ENABLE_OVERLOADING
data RWLockClearMethodInfo
instance (signature ~ (m ()), MonadIO m) => O.MethodInfo RWLockClearMethodInfo RWLock signature where
    overloadedMethod _ = rWLockClear

#endif

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

foreign import ccall "g_rw_lock_init" g_rw_lock_init :: 
    Ptr RWLock ->                           -- rw_lock : TInterface (Name {namespace = "GLib", name = "RWLock"})
    IO ()

{- |
Initializes a 'GI.GLib.Structs.RWLock.RWLock' so that it can be used.

This function is useful to initialize a lock that has been
allocated on the stack, or as part of a larger structure.  It is not
necessary to initialise a reader-writer lock that has been statically
allocated.


=== /C code/
>
>  typedef struct {
>    GRWLock l;
>    ...
>  } Blob;
>
>Blob *b;
>
>b = g_new (Blob, 1);
>g_rw_lock_init (&b->l);


To undo the effect of 'GI.GLib.Structs.RWLock.rWLockInit' when a lock is no longer
needed, use 'GI.GLib.Structs.RWLock.rWLockClear'.

Calling 'GI.GLib.Structs.RWLock.rWLockInit' on an already initialized 'GI.GLib.Structs.RWLock.RWLock' leads
to undefined behaviour.

/Since: 2.32/
-}
rWLockInit ::
    (B.CallStack.HasCallStack, MonadIO m) =>
    RWLock
    {- ^ /@rwLock@/: an uninitialized 'GI.GLib.Structs.RWLock.RWLock' -}
    -> m ()
rWLockInit :: RWLock -> m ()
rWLockInit rwLock :: RWLock
rwLock = IO () -> m ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> m ()) -> IO () -> m ()
forall a b. (a -> b) -> a -> b
$ do
    Ptr RWLock
rwLock' <- RWLock -> IO (Ptr RWLock)
forall a. (HasCallStack, ManagedPtrNewtype a) => a -> IO (Ptr a)
unsafeManagedPtrGetPtr RWLock
rwLock
    Ptr RWLock -> IO ()
g_rw_lock_init Ptr RWLock
rwLock'
    RWLock -> IO ()
forall a. ManagedPtrNewtype a => a -> IO ()
touchManagedPtr RWLock
rwLock
    () -> IO ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()

#if ENABLE_OVERLOADING
data RWLockInitMethodInfo
instance (signature ~ (m ()), MonadIO m) => O.MethodInfo RWLockInitMethodInfo RWLock signature where
    overloadedMethod _ = rWLockInit

#endif

-- method RWLock::reader_lock
-- method type : OrdinaryMethod
-- Args : [Arg {argCName = "rw_lock", argType = TInterface (Name {namespace = "GLib", name = "RWLock"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a #GRWLock", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing}]
-- Lengths : []
-- returnType : Nothing
-- throws : False
-- Skip return : False

foreign import ccall "g_rw_lock_reader_lock" g_rw_lock_reader_lock :: 
    Ptr RWLock ->                           -- rw_lock : TInterface (Name {namespace = "GLib", name = "RWLock"})
    IO ()

{- |
Obtain a read lock on /@rwLock@/. If another thread currently holds
the write lock on /@rwLock@/, the current thread will block. If another thread
does not hold the write lock, but is waiting for it, it is implementation
defined whether the reader or writer will block. Read locks can be taken
recursively.

It is implementation-defined how many threads are allowed to
hold read locks on the same lock simultaneously. If the limit is hit,
or if a deadlock is detected, a critical warning will be emitted.

/Since: 2.32/
-}
rWLockReaderLock ::
    (B.CallStack.HasCallStack, MonadIO m) =>
    RWLock
    {- ^ /@rwLock@/: a 'GI.GLib.Structs.RWLock.RWLock' -}
    -> m ()
rWLockReaderLock :: RWLock -> m ()
rWLockReaderLock rwLock :: RWLock
rwLock = IO () -> m ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> m ()) -> IO () -> m ()
forall a b. (a -> b) -> a -> b
$ do
    Ptr RWLock
rwLock' <- RWLock -> IO (Ptr RWLock)
forall a. (HasCallStack, ManagedPtrNewtype a) => a -> IO (Ptr a)
unsafeManagedPtrGetPtr RWLock
rwLock
    Ptr RWLock -> IO ()
g_rw_lock_reader_lock Ptr RWLock
rwLock'
    RWLock -> IO ()
forall a. ManagedPtrNewtype a => a -> IO ()
touchManagedPtr RWLock
rwLock
    () -> IO ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()

#if ENABLE_OVERLOADING
data RWLockReaderLockMethodInfo
instance (signature ~ (m ()), MonadIO m) => O.MethodInfo RWLockReaderLockMethodInfo RWLock signature where
    overloadedMethod _ = rWLockReaderLock

#endif

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

foreign import ccall "g_rw_lock_reader_trylock" g_rw_lock_reader_trylock :: 
    Ptr RWLock ->                           -- rw_lock : TInterface (Name {namespace = "GLib", name = "RWLock"})
    IO CInt

{- |
Tries to obtain a read lock on /@rwLock@/ and returns 'True' if
the read lock was successfully obtained. Otherwise it
returns 'False'.

/Since: 2.32/
-}
rWLockReaderTrylock ::
    (B.CallStack.HasCallStack, MonadIO m) =>
    RWLock
    {- ^ /@rwLock@/: a 'GI.GLib.Structs.RWLock.RWLock' -}
    -> m Bool
    {- ^ __Returns:__ 'True' if /@rwLock@/ could be locked -}
rWLockReaderTrylock :: RWLock -> m Bool
rWLockReaderTrylock rwLock :: RWLock
rwLock = IO Bool -> m Bool
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
    Ptr RWLock
rwLock' <- RWLock -> IO (Ptr RWLock)
forall a. (HasCallStack, ManagedPtrNewtype a) => a -> IO (Ptr a)
unsafeManagedPtrGetPtr RWLock
rwLock
    CInt
result <- Ptr RWLock -> IO CInt
g_rw_lock_reader_trylock Ptr RWLock
rwLock'
    let result' :: Bool
result' = (CInt -> CInt -> Bool
forall a. Eq a => a -> a -> Bool
/= 0) CInt
result
    RWLock -> IO ()
forall a. ManagedPtrNewtype a => a -> IO ()
touchManagedPtr RWLock
rwLock
    Bool -> IO Bool
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
result'

#if ENABLE_OVERLOADING
data RWLockReaderTrylockMethodInfo
instance (signature ~ (m Bool), MonadIO m) => O.MethodInfo RWLockReaderTrylockMethodInfo RWLock signature where
    overloadedMethod _ = rWLockReaderTrylock

#endif

-- method RWLock::reader_unlock
-- method type : OrdinaryMethod
-- Args : [Arg {argCName = "rw_lock", argType = TInterface (Name {namespace = "GLib", name = "RWLock"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a #GRWLock", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing}]
-- Lengths : []
-- returnType : Nothing
-- throws : False
-- Skip return : False

foreign import ccall "g_rw_lock_reader_unlock" g_rw_lock_reader_unlock :: 
    Ptr RWLock ->                           -- rw_lock : TInterface (Name {namespace = "GLib", name = "RWLock"})
    IO ()

{- |
Release a read lock on /@rwLock@/.

Calling 'GI.GLib.Structs.RWLock.rWLockReaderUnlock' on a lock that is not held
by the current thread leads to undefined behaviour.

/Since: 2.32/
-}
rWLockReaderUnlock ::
    (B.CallStack.HasCallStack, MonadIO m) =>
    RWLock
    {- ^ /@rwLock@/: a 'GI.GLib.Structs.RWLock.RWLock' -}
    -> m ()
rWLockReaderUnlock :: RWLock -> m ()
rWLockReaderUnlock rwLock :: RWLock
rwLock = IO () -> m ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> m ()) -> IO () -> m ()
forall a b. (a -> b) -> a -> b
$ do
    Ptr RWLock
rwLock' <- RWLock -> IO (Ptr RWLock)
forall a. (HasCallStack, ManagedPtrNewtype a) => a -> IO (Ptr a)
unsafeManagedPtrGetPtr RWLock
rwLock
    Ptr RWLock -> IO ()
g_rw_lock_reader_unlock Ptr RWLock
rwLock'
    RWLock -> IO ()
forall a. ManagedPtrNewtype a => a -> IO ()
touchManagedPtr RWLock
rwLock
    () -> IO ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()

#if ENABLE_OVERLOADING
data RWLockReaderUnlockMethodInfo
instance (signature ~ (m ()), MonadIO m) => O.MethodInfo RWLockReaderUnlockMethodInfo RWLock signature where
    overloadedMethod _ = rWLockReaderUnlock

#endif

-- method RWLock::writer_lock
-- method type : OrdinaryMethod
-- Args : [Arg {argCName = "rw_lock", argType = TInterface (Name {namespace = "GLib", name = "RWLock"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a #GRWLock", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing}]
-- Lengths : []
-- returnType : Nothing
-- throws : False
-- Skip return : False

foreign import ccall "g_rw_lock_writer_lock" g_rw_lock_writer_lock :: 
    Ptr RWLock ->                           -- rw_lock : TInterface (Name {namespace = "GLib", name = "RWLock"})
    IO ()

{- |
Obtain a write lock on /@rwLock@/. If any thread already holds
a read or write lock on /@rwLock@/, the current thread will block
until all other threads have dropped their locks on /@rwLock@/.

/Since: 2.32/
-}
rWLockWriterLock ::
    (B.CallStack.HasCallStack, MonadIO m) =>
    RWLock
    {- ^ /@rwLock@/: a 'GI.GLib.Structs.RWLock.RWLock' -}
    -> m ()
rWLockWriterLock :: RWLock -> m ()
rWLockWriterLock rwLock :: RWLock
rwLock = IO () -> m ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> m ()) -> IO () -> m ()
forall a b. (a -> b) -> a -> b
$ do
    Ptr RWLock
rwLock' <- RWLock -> IO (Ptr RWLock)
forall a. (HasCallStack, ManagedPtrNewtype a) => a -> IO (Ptr a)
unsafeManagedPtrGetPtr RWLock
rwLock
    Ptr RWLock -> IO ()
g_rw_lock_writer_lock Ptr RWLock
rwLock'
    RWLock -> IO ()
forall a. ManagedPtrNewtype a => a -> IO ()
touchManagedPtr RWLock
rwLock
    () -> IO ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()

#if ENABLE_OVERLOADING
data RWLockWriterLockMethodInfo
instance (signature ~ (m ()), MonadIO m) => O.MethodInfo RWLockWriterLockMethodInfo RWLock signature where
    overloadedMethod _ = rWLockWriterLock

#endif

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

foreign import ccall "g_rw_lock_writer_trylock" g_rw_lock_writer_trylock :: 
    Ptr RWLock ->                           -- rw_lock : TInterface (Name {namespace = "GLib", name = "RWLock"})
    IO CInt

{- |
Tries to obtain a write lock on /@rwLock@/. If any other thread holds
a read or write lock on /@rwLock@/, it immediately returns 'False'.
Otherwise it locks /@rwLock@/ and returns 'True'.

/Since: 2.32/
-}
rWLockWriterTrylock ::
    (B.CallStack.HasCallStack, MonadIO m) =>
    RWLock
    {- ^ /@rwLock@/: a 'GI.GLib.Structs.RWLock.RWLock' -}
    -> m Bool
    {- ^ __Returns:__ 'True' if /@rwLock@/ could be locked -}
rWLockWriterTrylock :: RWLock -> m Bool
rWLockWriterTrylock rwLock :: RWLock
rwLock = IO Bool -> m Bool
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
    Ptr RWLock
rwLock' <- RWLock -> IO (Ptr RWLock)
forall a. (HasCallStack, ManagedPtrNewtype a) => a -> IO (Ptr a)
unsafeManagedPtrGetPtr RWLock
rwLock
    CInt
result <- Ptr RWLock -> IO CInt
g_rw_lock_writer_trylock Ptr RWLock
rwLock'
    let result' :: Bool
result' = (CInt -> CInt -> Bool
forall a. Eq a => a -> a -> Bool
/= 0) CInt
result
    RWLock -> IO ()
forall a. ManagedPtrNewtype a => a -> IO ()
touchManagedPtr RWLock
rwLock
    Bool -> IO Bool
forall (m :: * -> *) a. Monad m => a -> m a
return Bool
result'

#if ENABLE_OVERLOADING
data RWLockWriterTrylockMethodInfo
instance (signature ~ (m Bool), MonadIO m) => O.MethodInfo RWLockWriterTrylockMethodInfo RWLock signature where
    overloadedMethod _ = rWLockWriterTrylock

#endif

-- method RWLock::writer_unlock
-- method type : OrdinaryMethod
-- Args : [Arg {argCName = "rw_lock", argType = TInterface (Name {namespace = "GLib", name = "RWLock"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a #GRWLock", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing}]
-- Lengths : []
-- returnType : Nothing
-- throws : False
-- Skip return : False

foreign import ccall "g_rw_lock_writer_unlock" g_rw_lock_writer_unlock :: 
    Ptr RWLock ->                           -- rw_lock : TInterface (Name {namespace = "GLib", name = "RWLock"})
    IO ()

{- |
Release a write lock on /@rwLock@/.

Calling 'GI.GLib.Structs.RWLock.rWLockWriterUnlock' on a lock that is not held
by the current thread leads to undefined behaviour.

/Since: 2.32/
-}
rWLockWriterUnlock ::
    (B.CallStack.HasCallStack, MonadIO m) =>
    RWLock
    {- ^ /@rwLock@/: a 'GI.GLib.Structs.RWLock.RWLock' -}
    -> m ()
rWLockWriterUnlock :: RWLock -> m ()
rWLockWriterUnlock rwLock :: RWLock
rwLock = IO () -> m ()
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO () -> m ()) -> IO () -> m ()
forall a b. (a -> b) -> a -> b
$ do
    Ptr RWLock
rwLock' <- RWLock -> IO (Ptr RWLock)
forall a. (HasCallStack, ManagedPtrNewtype a) => a -> IO (Ptr a)
unsafeManagedPtrGetPtr RWLock
rwLock
    Ptr RWLock -> IO ()
g_rw_lock_writer_unlock Ptr RWLock
rwLock'
    RWLock -> IO ()
forall a. ManagedPtrNewtype a => a -> IO ()
touchManagedPtr RWLock
rwLock
    () -> IO ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()

#if ENABLE_OVERLOADING
data RWLockWriterUnlockMethodInfo
instance (signature ~ (m ()), MonadIO m) => O.MethodInfo RWLockWriterUnlockMethodInfo RWLock signature where
    overloadedMethod _ = rWLockWriterUnlock

#endif

#if ENABLE_OVERLOADING
type family ResolveRWLockMethod (t :: Symbol) (o :: *) :: * where
    ResolveRWLockMethod "clear" o = RWLockClearMethodInfo
    ResolveRWLockMethod "init" o = RWLockInitMethodInfo
    ResolveRWLockMethod "readerLock" o = RWLockReaderLockMethodInfo
    ResolveRWLockMethod "readerTrylock" o = RWLockReaderTrylockMethodInfo
    ResolveRWLockMethod "readerUnlock" o = RWLockReaderUnlockMethodInfo
    ResolveRWLockMethod "writerLock" o = RWLockWriterLockMethodInfo
    ResolveRWLockMethod "writerTrylock" o = RWLockWriterTrylockMethodInfo
    ResolveRWLockMethod "writerUnlock" o = RWLockWriterUnlockMethodInfo
    ResolveRWLockMethod l o = O.MethodResolutionFailed l o

instance (info ~ ResolveRWLockMethod t RWLock, O.MethodInfo info RWLock p) => O.IsLabelProxy t (RWLock -> p) where
    fromLabelProxy _ = O.overloadedMethod (O.MethodProxy :: O.MethodProxy info)

#if MIN_VERSION_base(4,9,0)
instance (info ~ ResolveRWLockMethod t RWLock, O.MethodInfo info RWLock p) => O.IsLabel t (RWLock -> 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