Reference Manual

Main Page | Namespace List | Class Hierarchy | Alphabetical List | Compound List | File List | Namespace Members | Compound Members | File Members

# Inti::G::StaticRWLock Struct Reference

A compile-time GStaticRWlock C++ wrapper interface. More...

`#include <inti/glib/mutex.h>`

Inheritance diagram for Inti::G::StaticRWLock:

List of all members.

## Public Member Functions

Constructors

- void init ()
    Initializes a StaticRWLock. Alternatively you can initialize it with G::INTI_STATIC_RW_LOCK_INIT.

Accessors

- GStaticRWLock * g_static_rw_lock () const
    Get a pointer to the GStaticRWLock object.
- operator GStaticRWLock * () const
    Conversion operator; Safely converts a G::StaticRWLock object into a GStaticRWLock pointer.

Methods

- void reader_lock ()
    Locks a lock for reading.
- bool reader_trylock ()
    Tries to lock the lock for reading.
- void reader_unlock ()
    Unlocks the lock.
- void writer_lock ()
    Locks the lock for writing.
- bool writer_trylock ()
    Tries to lock the lock for writing.
- void writer_unlock ()
    Unlocks the lock.

## Detailed Description

A compile-time GStaticRWlock C++ wrapper interface.

StaticRWLock represents a read-write lock. A read-write lock can be used for protecting data, that some portions of code only read from, while others also write. In such situations it is desirable, that several readers can read at once, whereas of course only one writer may write at a time. Take a look at the following example:

Example: An array with access functions.

        G::StaticRWLock rwlock = INTI_STATIC_RW_LOCK_INIT;
        GPtrArray *array;

        void* my_array_get(unsigned int index)
        {
            void *retval = 0;

            if (!array)
                    return 0;

            rw_lock.reader_lock();

            if (index < array->len)
                    retval = g_ptr_array_index(array, index);

            rwlock.reader_unlock();

            return retval;
        }

        void my_array_set(unsigned int index, void *data)
        {
            rwlock.writer_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;

            rwlock.writer_unlock();
        }

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 once 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.

Most of the time the writers should have precedence over readers. That means for this implementation, that as soon as a writer wants to lock the data, no other reader is allowed to lock the data, whereas of course the readers, that already have locked the data are allowed to finish their operation. As soon as the last reader unlocks the data, the writer will lock it.

A read-write lock has a higher overhead than a mutex. For example both reader_lock() and reader_unlock() have to lock and unlock a StaticMutex, so it takes at least twice the time to lock and unlock a StaticRWLock than to lock and unlock a StaticMutex. So only data structures, that are accessed by multiple readers, which keep the lock for a considerable time justify a StaticRWLock. The above example most probably would fare better with a StaticMutex.

## Member Function Documentation

void Inti::G::StaticRWLock::reader_lock | ( |  | ) |

Locks a lock for reading.

There may be unlimited concurrent locks for reading of a StaticRWLock at the same time. If lock is already locked for writing by another thread or if another thread is already waiting to lock lock for writing, this function will block until lock is unlocked by the other writing thread and no other writing threads want to lock lock. This lock has to be unlocked by reader_unlock().

StaticRWLock is not recursive. It might seem to be possible to recursively lock for reading, but that can result in a deadlock as well, due to writer preference.

bool Inti::G::StaticRWLock::reader_trylock | ( |  | ) |

Tries to lock the lock for reading.

Returns:
  true if lock could be locked for reading.

If lock is already locked for writing by another thread or if another thread is already waiting to lock lock for writing, it immediately returns false. Otherwise it locks lock for reading and returns true. This lock has to be unlocked by reader_unlock().

void Inti::G::StaticRWLock::reader_unlock | ( |  | ) |

| Unlocks the lock. If a thread waits to lock the lock for writing and all locks for reading have been unlocked, the waiting thread is woken up and can lock lock for writing.

void Inti::G::StaticRWLock::writer_lock | ( |  | ) |

Locks the lock for writing.

If lock is already locked for writing or reading by other threads, this method will block until lock is completely unlocked and then lock the lock for writing. While this method waits to lock the lock, no other thread can lock the lock for reading. When lock is locked for writing, no other thread can lock the lock (neither for reading nor writing). This lock has to be unlocked by writer_unlock().

bool Inti::G::StaticRWLock::writer_trylock | ( |  | ) |

Tries to lock the lock for writing.

Returns:
  true if lock could be locked for writing.

If lock is already locked (for either reading or writing) by another thread, it immediately returns false. Otherwise it locks the lock for writing and returns true. This lock has to be unlocked by writer_unlock().

void Inti::G::StaticRWLock::writer_unlock | ( |  | ) |

| Unlocks the lock. If a thread waits to lock the lock for writing and all locks for reading have been unlocked, the waiting thread is woken up and can lock the lock for writing. If no thread waits to lock the lock for writing and threads wait to lock the lock for reading, the waiting threads are woken up and can lock the lock for reading.

The documentation for this struct was generated from the following file:

- mutex.h

Main Page - Footer