###  | # Boost.Threads ## Header <boost/thread/recursive_mutex.hpp>

## Contents

Introduction
Classes

Class `recursive_mutex`

Class `recursive_mutex` synopsis
Class `recursive_mutex` constructors and destructor

Class `recursive_try_mutex`

Class `recursive_try_mutex` synopsis
Class `recursive_try_mutex` constructors and destructor

Class `recursive_timed_mutex`

Class `recursive_timed_mutex` synopsis
Class `recursive_timed_mutex` constructors and destructor

Example(s)

## Introduction

Include the header <boost/thread/recursive_mutex.hpp> to define the recursive_mutex, recursive_try_mutex and recursive_timed_mutex classes.

The recursive_mutex, recursive_try_mutex and recursive_timed_mutex classes are models of Mutex, TryMutex, and TimedMutex respectively. These types should be used to synchronize access to shared resources when recursive locking by a single thread is likely to occur. A good example for this is when a class supplies "internal synchronization" to ensure thread-safety and a function of the class may have to call other functions of the class which also attempt to lock the mutex. For recursive locking mechanics, see mutexes.

Each class supplies one or more typedefs for lock types which model matching lock concepts. For the best possible performance you should use the mutex class that supports the minimum set of lock types that you need.

Mutex Class | Lock name | Lock Concept
`recursive_mutex` | `scoped_lock` | ScopedLock
`recursive_try_mutex` | `scoped_lock scoped_try_lock` | ScopedLock ScopedTryLock
`recursive_timed_mutex` | `scoped_lock scoped_try_lock scoped_timed_lock` | ScopedLock ScopedTryLock ScopedTimedLock

The `recursive_mutex`, `recursive_try_mutex` and `recursive_timed_mutex` employ a `Recursive` locking strategy, so attempts to recursively lock them succeed and an internal "lock count" is maintained. Attempts to unlock them by a thread that does not own a lock on them will result in undefined behavior.

The `recursive_mutex`, `recursive_try_mutex` and `recursive_timed_mutex` leave the scheduling policy as `Unspecified`. Programmers should assume that threads waiting for a lock on objects of these types acquire the lock in a random order, even though the specific behavior for a given platform may be different.

## Classes

### Class `recursive_mutex`

The `recursive_mutex` class is a model of Mutex and NonCopyable, and provides no additional facilities beyond the requirements of these concepts.

#### Class `recursive_mutex` synopsis

    namespace boost
    {
        class recursive_mutex : private boost::noncopyable // Exposition only.
            // Class recursive_mutex meets the NonCopyable requirement.
        {
        public:
            typedef [implementation defined; see Introduction] scoped_lock;

            recursive_mutex();
            ~recursive_mutex();
        };
    };

#### Class `recursive_mutex` constructors and destructor

    recursive_mutex();

Postconditions: `*this` is in an unlocked state.

    ~recursive_mutex();

Requires: `*this` is in an unlocked sate.
Danger: Destruction of a locked mutex is a serious programming error resulting in undefined behavior such as a program crash.

### Class `recursive_try_mutex`

The `recursive_try_mutex` class is a model of TryMutex and NonCopyable, and provides no additional facilities beyond the requirements of these concepts.

#### Class `recursive_try_mutex` synopsis

    namespace boost
    {
        class recursive_mutex : private boost::noncopyable // Exposition only.
            // Class recursive_mutex meets the NonCopyable requirement.
        {
        Public:
            typedef [implementation defined; see Introduction] scoped_lock;
            typedef [implementation defined; see Introduction] scoped_try_lock;

            recursive_try_mutex();
            ~recursive_try_mutex();
        };
    };

#### Class `recursive_try_mutex` constructors and destructor

    recursive_try_mutex();

Postconditions: `*this` is in an unlocked state.

    ~recursive_try_mutex();

Requires: `*this` is in an unlocked sate.
Danger: Destruction of a locked mutex is a serious programming error resulting in undefined behavior such as a program crash.

### Class `recursive_timed_mutex`

The `recursive_timed_mutex` class is a model of TimedMutex and NonCopyable, and provides no additional facilities beyond the requirements of these concepts.

#### Class `recursive_timed_mutex` synopsis

    namespace boost
    {
        class recursive_timed_mutex : private boost::noncopyable // Exposition only.
            // Class recursive_mutex meets the NonCopyable requirement.
        {
        Public:
            typedef [implementation defined; see Introduction] scoped_lock;
            typedef [implementation defined; see Introduction] scoped_try_lock;
            typedef [implementation defined; see Introduction] scoped_timed_lock;

            recursive_timed_mutex();
            ~recursive_timed_mutex();
        };
    };

#### Class `recursive_timed_mutex` constructors and destructor

    recursive_timed_mutex();

Postconditions: `*this` is in an unlocked state.

    ~recursive_timed_mutex();

Requires: `*this` is in an unlocked sate.
Danger: Destruction of a locked mutex is a serious programming error resulting in undefined behavior such as a program crash.

## Example(s)

    #include <boost/thread/recursive_mutex.hpp>
    #include <boost/thread/thread.hpp>
    #include <iostream>

    class counter
    {
    public:
        counter() : count(0) { }

        int add(int val) {
            boost::recursive_mutex::scoped_lock scoped_lock(mutex);
            count += val;
            return count;
        }
        int increment() {
            boost::recursive_mutex::scoped_lock scoped_lock(mutex);
            return add(1);
        }

    private:
        boost::recursive_mutex mutex;
        int count;
    };

    counter c;

    void change_count(void*)
    {
        std::cout << "count == " << c.increment() << std::endl;
    }

    int main(int, char*[])
    {
        const int num_threads=4;

        boost::thread_group threads;
        for (int i=0; i < num_threads; ++i)
            threads.create_thread(&change_count, 0);

        threads.join_all();

        return 0;
    }

The output is:

    count == 1
    count == 2
    count == 3
    count == 4

Revised 05 November, 2001

© Copyright William E. Kempf 2001-2002. All Rights Reserved.

Permission to use, copy, modify, distribute and sell this software and its documentation for any purpose is hereby granted without fee, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation. William E. Kempf makes no representations about the suitability of this software for any purpose. It is provided "as is" without express or implied warranty.