Xfce Foundation Classes
Main Page  | IndexNamespace List  |  Alphabetical List  |  Class List  |  File List


Xfc::G::Mutex Class Reference

A GMutex C++ wrapper interface. More...

#include <xfc/glib/mutex.hh>

Inheritance diagram for Xfc::G::Mutex:

Xfc::Object Xfc::Trackable List of all members.

Public Member Functions

Accessors
Methods

Detailed Description

A GMutex C++ wrapper interface.

Mutex is an object that represents a mutex (mutual exclusion). It can be used to protect data against shared access. Take for example the following function:

Example 1:. A method which will not work in a threaded environment.

 int give_me_next_number()
 {
        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 first naive implementation would be:

Example 2: The wrong way to write a thread-safe method.

 int give_me_next_number ()
 {
        static int current_number = 0;

        G::Mutex *mutex = 0;
        if (!mutex)
                mutex = new G::Mutex;

        mutex->lock();
        int result = current_number = calc_next_number(current_number);
        mutex->unlock();
        return result;
 }

This looks like it would work, but there is a race condition while constructing the mutex and this code cannot work reliably. So please do not use such constructs in your own programs. One working solution is:

Example 3: A correct thread-safe method.

 G::Mutex *give_me_next_number_mutex = 0;

 // This method must be called exactly once before any call to give_me_next_number().
 void init_give_me_next_number()
 {
        if (!give_me_next_number_mutex)
                give_me_next_number_mutex = new G::Mutex;
 }

 int give_me_next_number()
 {
        static int current_number = 0;
        give_me_next_number_mutex->lock();
        int result = current_number = calc_next_number(current_number);
        give_me_next_number_mutex->unlock();
        return result;
 }


Constructor & Destructor Documentation

Xfc::G::Mutex::Mutex ( bool  lock_mutex = false  ) 

Construct a new mutex.

Parameters:
lock_mutex Whether to lock the mutex at construction time.
If the mutex is locked at construction time it will automatically be unlocked when it goes out of scope. Note this constructor will abort, if G::Thread::init() has not been called yet.

Xfc::G::Mutex::Mutex ( bool  lock_mutex = false  ) 

Construct a new mutex.

Parameters:
lock_mutex Whether to lock the mutex at construction time.
If the mutex is locked at construction time it will automatically be unlocked when it goes out of scope. Note this constructor will abort, if G::Thread::init() has not been called yet.


Member Function Documentation

bool Xfc::G::Mutex::is_locked (  )  const

Determines whether the mutex is locked.

Returns:
true if the mutex is locked.

void Xfc::G::Mutex::lock (  ) 

Locks the mutex.

If mutex is already locked by another thread, the current thread will block until the mutex is unlocked by the other thread. This method can also be used if G::Thread::init() has not yet been called, in which case it will do nothing.

Note Mutex is neither guaranteed to be recursive nor to be non-recursive, that is, a thread could deadlock while calling lock(), if it already has locked the mutex. Use G::StaticRecMutex, if you need a recursive mutex.

bool Xfc::G::Mutex::trylock (  ) 

Tries to lock the mutex.

Returns:
true if mutex could be locked.
If the mutex is already locked by another thread, it immediately returns false. Otherwise it locks mutex and returns true. This method can also be used if G::Thread::init() has not yet been called, in which case it will immediately return true.

Note Mutex is neither guaranteed to be recursive nor to be non-recursive, that is, the return value of trylock() could be both false or true, if the current thread already has locked the mutex. Use G::StaticRecMutex, if you need a recursive mutex.

void Xfc::G::Mutex::unlock (  ) 

Unlocks the mutex.

If another thread is blocked in a lock() call for the mutex, it will be woken and can lock the mutex itself. This method can also be used if G::Thread::init() has not yet been called, in which case it will do nothing.


The documentation for this class was generated from the following file: Xfce Foundation Classes
Copyright © 2004-2005 The XFC Development Team XFC 4.3