{- | 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 #GMutex 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 g_rw_lock_writer_lock()), multiple threads can gain simultaneous read-only access (by holding the 'reader' lock via g_rw_lock_reader_lock()). Here is an example for an array with access functions: |[ 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 #GRWLock is allocated in static storage then it can be used without initialisation. Otherwise, you should call g_rw_lock_init() on it and g_rw_lock_clear() when done. A GRWLock should only be accessed with the g_rw_lock_ functions. -} module GI.GLib.Structs.RWLock ( -- * Exported types RWLock(..) , noRWLock , -- * Methods -- ** rWLockClear rWLockClear , -- ** rWLockInit rWLockInit , -- ** rWLockReaderLock rWLockReaderLock , -- ** rWLockReaderTrylock rWLockReaderTrylock , -- ** rWLockReaderUnlock rWLockReaderUnlock , -- ** rWLockWriterLock rWLockWriterLock , -- ** rWLockWriterTrylock rWLockWriterTrylock , -- ** rWLockWriterUnlock rWLockWriterUnlock , ) where import Prelude () import Data.GI.Base.ShortPrelude import qualified Data.Text as T import qualified Data.ByteString.Char8 as B import qualified Data.Map as Map import GI.GLib.Types import GI.GLib.Callbacks newtype RWLock = RWLock (ForeignPtr RWLock) noRWLock :: Maybe RWLock noRWLock = Nothing -- method RWLock::clear -- method type : OrdinaryMethod -- Args : [Arg {argName = "_obj", argType = TInterface "GLib" "RWLock", direction = DirectionIn, mayBeNull = False, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, transfer = TransferNothing}] -- Lengths : [] -- hInArgs : [Arg {argName = "_obj", argType = TInterface "GLib" "RWLock", direction = DirectionIn, mayBeNull = False, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, transfer = TransferNothing}] -- returnType : TBasicType TVoid -- throws : False -- Skip return : False foreign import ccall "g_rw_lock_clear" g_rw_lock_clear :: Ptr RWLock -> -- _obj : TInterface "GLib" "RWLock" IO () rWLockClear :: (MonadIO m) => RWLock -> -- _obj m () rWLockClear _obj = liftIO $ do let _obj' = unsafeManagedPtrGetPtr _obj g_rw_lock_clear _obj' touchManagedPtr _obj return () -- method RWLock::init -- method type : OrdinaryMethod -- Args : [Arg {argName = "_obj", argType = TInterface "GLib" "RWLock", direction = DirectionIn, mayBeNull = False, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, transfer = TransferNothing}] -- Lengths : [] -- hInArgs : [Arg {argName = "_obj", argType = TInterface "GLib" "RWLock", direction = DirectionIn, mayBeNull = False, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, transfer = TransferNothing}] -- returnType : TBasicType TVoid -- throws : False -- Skip return : False foreign import ccall "g_rw_lock_init" g_rw_lock_init :: Ptr RWLock -> -- _obj : TInterface "GLib" "RWLock" IO () rWLockInit :: (MonadIO m) => RWLock -> -- _obj m () rWLockInit _obj = liftIO $ do let _obj' = unsafeManagedPtrGetPtr _obj g_rw_lock_init _obj' touchManagedPtr _obj return () -- method RWLock::reader_lock -- method type : OrdinaryMethod -- Args : [Arg {argName = "_obj", argType = TInterface "GLib" "RWLock", direction = DirectionIn, mayBeNull = False, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, transfer = TransferNothing}] -- Lengths : [] -- hInArgs : [Arg {argName = "_obj", argType = TInterface "GLib" "RWLock", direction = DirectionIn, mayBeNull = False, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, transfer = TransferNothing}] -- returnType : TBasicType TVoid -- throws : False -- Skip return : False foreign import ccall "g_rw_lock_reader_lock" g_rw_lock_reader_lock :: Ptr RWLock -> -- _obj : TInterface "GLib" "RWLock" IO () rWLockReaderLock :: (MonadIO m) => RWLock -> -- _obj m () rWLockReaderLock _obj = liftIO $ do let _obj' = unsafeManagedPtrGetPtr _obj g_rw_lock_reader_lock _obj' touchManagedPtr _obj return () -- method RWLock::reader_trylock -- method type : OrdinaryMethod -- Args : [Arg {argName = "_obj", argType = TInterface "GLib" "RWLock", direction = DirectionIn, mayBeNull = False, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, transfer = TransferNothing}] -- Lengths : [] -- hInArgs : [Arg {argName = "_obj", argType = TInterface "GLib" "RWLock", direction = DirectionIn, mayBeNull = False, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, transfer = TransferNothing}] -- returnType : TBasicType TBoolean -- throws : False -- Skip return : False foreign import ccall "g_rw_lock_reader_trylock" g_rw_lock_reader_trylock :: Ptr RWLock -> -- _obj : TInterface "GLib" "RWLock" IO CInt rWLockReaderTrylock :: (MonadIO m) => RWLock -> -- _obj m Bool rWLockReaderTrylock _obj = liftIO $ do let _obj' = unsafeManagedPtrGetPtr _obj result <- g_rw_lock_reader_trylock _obj' let result' = (/= 0) result touchManagedPtr _obj return result' -- method RWLock::reader_unlock -- method type : OrdinaryMethod -- Args : [Arg {argName = "_obj", argType = TInterface "GLib" "RWLock", direction = DirectionIn, mayBeNull = False, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, transfer = TransferNothing}] -- Lengths : [] -- hInArgs : [Arg {argName = "_obj", argType = TInterface "GLib" "RWLock", direction = DirectionIn, mayBeNull = False, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, transfer = TransferNothing}] -- returnType : TBasicType TVoid -- throws : False -- Skip return : False foreign import ccall "g_rw_lock_reader_unlock" g_rw_lock_reader_unlock :: Ptr RWLock -> -- _obj : TInterface "GLib" "RWLock" IO () rWLockReaderUnlock :: (MonadIO m) => RWLock -> -- _obj m () rWLockReaderUnlock _obj = liftIO $ do let _obj' = unsafeManagedPtrGetPtr _obj g_rw_lock_reader_unlock _obj' touchManagedPtr _obj return () -- method RWLock::writer_lock -- method type : OrdinaryMethod -- Args : [Arg {argName = "_obj", argType = TInterface "GLib" "RWLock", direction = DirectionIn, mayBeNull = False, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, transfer = TransferNothing}] -- Lengths : [] -- hInArgs : [Arg {argName = "_obj", argType = TInterface "GLib" "RWLock", direction = DirectionIn, mayBeNull = False, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, transfer = TransferNothing}] -- returnType : TBasicType TVoid -- throws : False -- Skip return : False foreign import ccall "g_rw_lock_writer_lock" g_rw_lock_writer_lock :: Ptr RWLock -> -- _obj : TInterface "GLib" "RWLock" IO () rWLockWriterLock :: (MonadIO m) => RWLock -> -- _obj m () rWLockWriterLock _obj = liftIO $ do let _obj' = unsafeManagedPtrGetPtr _obj g_rw_lock_writer_lock _obj' touchManagedPtr _obj return () -- method RWLock::writer_trylock -- method type : OrdinaryMethod -- Args : [Arg {argName = "_obj", argType = TInterface "GLib" "RWLock", direction = DirectionIn, mayBeNull = False, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, transfer = TransferNothing}] -- Lengths : [] -- hInArgs : [Arg {argName = "_obj", argType = TInterface "GLib" "RWLock", direction = DirectionIn, mayBeNull = False, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, transfer = TransferNothing}] -- returnType : TBasicType TBoolean -- throws : False -- Skip return : False foreign import ccall "g_rw_lock_writer_trylock" g_rw_lock_writer_trylock :: Ptr RWLock -> -- _obj : TInterface "GLib" "RWLock" IO CInt rWLockWriterTrylock :: (MonadIO m) => RWLock -> -- _obj m Bool rWLockWriterTrylock _obj = liftIO $ do let _obj' = unsafeManagedPtrGetPtr _obj result <- g_rw_lock_writer_trylock _obj' let result' = (/= 0) result touchManagedPtr _obj return result' -- method RWLock::writer_unlock -- method type : OrdinaryMethod -- Args : [Arg {argName = "_obj", argType = TInterface "GLib" "RWLock", direction = DirectionIn, mayBeNull = False, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, transfer = TransferNothing}] -- Lengths : [] -- hInArgs : [Arg {argName = "_obj", argType = TInterface "GLib" "RWLock", direction = DirectionIn, mayBeNull = False, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, transfer = TransferNothing}] -- returnType : TBasicType TVoid -- throws : False -- Skip return : False foreign import ccall "g_rw_lock_writer_unlock" g_rw_lock_writer_unlock :: Ptr RWLock -> -- _obj : TInterface "GLib" "RWLock" IO () rWLockWriterUnlock :: (MonadIO m) => RWLock -> -- _obj m () rWLockWriterUnlock _obj = liftIO $ do let _obj' = unsafeManagedPtrGetPtr _obj g_rw_lock_writer_unlock _obj' touchManagedPtr _obj return ()