FXMutex, FXMutexLock and FXThread

The new FXMutex, FXMutexLock and FXThread classes provide platform-independent facilities for multithreaded applications. This section will briefly describe the capabilites of those classes but it is assumed that the reader already has some background in programming multithreaded applications and understands the various problems one can get into when doing so.

The constructor for FXMutex doesn't require any arguments. To lock (or acquire) the mutex, call its lock() member function. If the mutex is already locked, the calling thread will block until the mutex becomes available. When lock() returns, the mutex will be in a locked state (with the calling thread as its owner). If you'd prefer a non-blocking version, call the trylock() member function instead. The trylock() member function immediately returns either TRUE, indicating that the calling thread was able to immediately acquire the lock, or FALSE, indicating that it wasn't. Finally, when you're through with the resource(s) protected by the mutex, be sure to call its unlock() member function to release the mutex. Here's a short code example to demonstrate the use of FXMutex:

class Application {
private:
    FXMutex databaseMutex;

public:
    void modifyDatabase() {
        databaseMutex.lock();
        database->modify();
        databaseMutex.unlock();
    }
};

The FXMutexLock class builds on the basic FXMutex class and provides an even more convenient way to protect a critical section of code by a mutex. When an FXMutexLock object is constructed, it accepts a reference to an FXMutex and locks it. When the FXMutexLock object goes out of scope, and its destructor is called, it unlocks the mutex. So we could rewrite the modifyDatabase() member function from the previous example using an FXMutexLock as follows:

void modifyDatabase()
{
    FXMutexLock mutexLock(databaseMutex);
    database->modify();
}

To be sure, the fact that this approach requires fewer lines of code is a plus, but there's a more subtle benfit as well. In the first example, if the call to database->modify() throws an exception it could leave the mutex in the locked state and that would be sad. In the latter example, since the FXMutexLock object was allocated on the stack, it's guaranteed to be destroyed before we exit this function, even in the presence of exceptions. This helps to ensure that your application won't become deadlocked.

Finally, the FXThread class is an abstract base class for creating additional threads of execution in an application. In order to use this class, you will need to subclass it and override its virtual run() member function.