gi-glib-2.0.17: GLib bindings

Copyright | Will Thompson Iñaki García Etxebarria and Jonas Platte
License | LGPL-2.1
Maintainer | Iñaki García Etxebarria (garetxe@gmail.com)
Safe Haskell | None
Language | Haskell2010

GI.GLib.Structs.RWLock

Contents

- Exported types
- Methods
  - clear
  - init
  - readerLock
  - readerTrylock
  - readerUnlock
  - writerLock
  - writerTrylock
  - writerUnlock

Description

The GRWLock struct is an opaque data structure to represent a reader-writer lock. It is similar to a `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 `rWLockWriterLock`), multiple threads can gain simultaneous read-only access (by holding the 'reader' lock via `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 `RWLock` is allocated in static storage then it can be used without initialisation. Otherwise, you should call `rWLockInit` on it and `rWLockClear` when done.

A GRWLock should only be accessed with the g_rw_lock_ functions.

Since: 2.32

Synopsis

- newtype RWLock = RWLock (ManagedPtr RWLock)
- newZeroRWLock :: MonadIO m => m RWLock
- noRWLock :: Maybe RWLock
- rWLockClear :: (HasCallStack, MonadIO m) => RWLock -> m ()
- rWLockInit :: (HasCallStack, MonadIO m) => RWLock -> m ()
- rWLockReaderLock :: (HasCallStack, MonadIO m) => RWLock -> m ()
- rWLockReaderTrylock :: (HasCallStack, MonadIO m) => RWLock -> m Bool
- rWLockReaderUnlock :: (HasCallStack, MonadIO m) => RWLock -> m ()
- rWLockWriterLock :: (HasCallStack, MonadIO m) => RWLock -> m ()
- rWLockWriterTrylock :: (HasCallStack, MonadIO m) => RWLock -> m Bool
- rWLockWriterUnlock :: (HasCallStack, MonadIO m) => RWLock -> m ()

# Exported types

newtype RWLock Source #

Memory-managed wrapper type.

Constructors

RWLock (ManagedPtr RWLock) |

Instances

WrappedPtr RWLock Source # |
Instance details Defined in GI.GLib.Structs.RWLock Methods wrappedPtrCalloc :: IO (Ptr RWLock) Source # wrappedPtrCopy :: RWLock -> IO RWLock Source # wrappedPtrFree :: Maybe (FunPtr (Ptr RWLock -> IO ())) Source #
tag ~ AttrSet => Constructible RWLock tag Source # |
Instance details Defined in GI.GLib.Structs.RWLock Methods new :: MonadIO m => (ManagedPtr RWLock -> RWLock) -> [AttrOp RWLock tag] -> m RWLock Source #

newZeroRWLock :: MonadIO m => m RWLock Source #

Construct a `RWLock` struct initialized to zero.

noRWLock :: Maybe RWLock Source #

A convenience alias for `Nothing` :: `Maybe` `RWLock`.

# Methods

## clear

rWLockClear Source #

Arguments

:: (HasCallStack, MonadIO m) |
=> RWLock | `rwLock`: an initialized `RWLock`
-> m () |

Frees the resources allocated to a lock with `rWLockInit`.

This function should not be used with a `RWLock` that has been statically allocated.

Calling `rWLockClear` when any thread holds the lock leads to undefined behaviour.

Sine: 2.32

## init

rWLockInit Source #

Arguments

:: (HasCallStack, MonadIO m) |
=> RWLock | `rwLock`: an uninitialized `RWLock`
-> m () |

Initializes a `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 `rWLockInit` when a lock is no longer needed, use `rWLockClear`.

Calling `rWLockInit` on an already initialized `RWLock` leads to undefined behaviour.

Since: 2.32

## readerLock

rWLockReaderLock Source #

Arguments

:: (HasCallStack, MonadIO m) |
=> RWLock | `rwLock`: a `RWLock`
-> m () |

Obtain a read lock on `rwLock`. If another thread currently holds the write lock on `rwLock` or blocks waiting for it, the current thread 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

## readerTrylock

rWLockReaderTrylock Source #

Arguments

:: (HasCallStack, MonadIO m) |
=> RWLock | `rwLock`: a `RWLock`
-> m Bool | Returns: `True` if `rwLock` could be locked

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

## readerUnlock

rWLockReaderUnlock Source #

Arguments

:: (HasCallStack, MonadIO m) |
=> RWLock | `rwLock`: a `RWLock`
-> m () |

Release a read lock on `rwLock`.

Calling `rWLockReaderUnlock` on a lock that is not held by the current thread leads to undefined behaviour.

Since: 2.32

## writerLock

rWLockWriterLock Source #

Arguments

:: (HasCallStack, MonadIO m) |
=> RWLock | `rwLock`: a `RWLock`
-> m () |

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

## writerTrylock

rWLockWriterTrylock Source #

Arguments

:: (HasCallStack, MonadIO m) |
=> RWLock | `rwLock`: a `RWLock`
-> m Bool | Returns: `True` if `rwLock` could be locked

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

## writerUnlock

rWLockWriterUnlock Source #

Arguments

:: (HasCallStack, MonadIO m) |
=> RWLock | `rwLock`: a `RWLock`
-> m () |

Release a write lock on `rwLock`.

Calling `rWLockWriterUnlock` on a lock that is not held by the current thread leads to undefined behaviour.

Since: 2.32