# FBB::SharedMutex(3bobcat)

## Shared Memory Mutex
(libbobcat-dev_6.06.02)

## 2005-2024

## NAME

FBB::SharedMutex - Mutex for shared memory

## SYNOPSIS

#include <bobcat/sharedmutex>
Linking option: -lpthread, -lbobcat

## DESCRIPTION

Shared memory may be used by multiple processes. To synchronize access to shared memory an FBB::SharedMutex may be defined inside a shared memory segment. SharedMutex objects allows clients to lock a shared memory segment before reading or writing its content. E.g., the Bobcat class FBB::SharedSegment defines a SharedMutex in its shared memory segment.

The SharedMutex class uses the facilities offered by the PThread library to implement (non recursive) shared memory locking. To force unlocking a (possibly) locked shared memory segment, its destructor can be called.

SharedMutex mutexes are non-recursive, resulting in deadlocks if their lock member is called twice from the same thread of execution without an intermediate call to unlock the mutex. If this causes concern, a variable can be defined indicating whether the lock has already been obtained.

## NAMESPACE

FBB
All constructors, members, operators and manipulators, mentioned in this man-page, are defined in the namespace FBB.

## INHERITS FROM

-

## CONSTRUCTORS, DESTRUCTOR

- SharedMutex():
  The default constructor initializes an FBB::SharedMutex object to a shared memory mutex (using the PTHREAD_PROCESS_SHARED attribute). As an FBB::SharedMutex object will normally be defined inside a shared memory segment the object's memory is already available. In this case placement new should be used to call the constructor. E.g., if a shared memory segment is attached to the current process at d_shared, and an FBB::SharedMutex should be defined at d_shared's address, then the FBB::SharedMutex object can be initialized like this:

          new (d_shared) FBB::SharedMutex;

  Caveat: when using placement new to initialize a SharedMutex make sure that the SharedMutex fits inside a block (i.e., shared.blockOffset() + sizeof(SharedMemory) < shared.dataSegmentSize()). If not, use seek to switch to an offset where this equality holds true, or simply use SharedMemory::create like this:

          FBB::SharedMemory::create<FBB::SharedMutex>();

- ~SharedMutex():
  The class's destructor releases all of the current process's nested shared memory segment locks. To destroy an FBB::SharedMutex object that has been constructed using the placement new operator use

      d_sharedMutex->~SharedMutex();

  (assuming SharedMutex *d_sharedMutex points to the location where placement new has previously initialized the FBB::SharedMutex object.)

Copy and move constructors (and assignment operators) are not available.

## MEMBER FUNCTIONS

- void lock() const:
  When returning from this member, the current process has locked the shared memory segment. Note that SharedMutex objects are non-recursive.

- void unlock() const:
  The object's lock of the shared memory segment is released. This member can also be called if the SharedMutex's lock has not been obtained.

## PROTECTED MEMBER FUNCTION

- pthread_mutex_t *mutexPtr():
  A pointer is returned to the pthread_mutex_t object used by the SharedMutex object;

## EXAMPLE

    #include <sys/types.h>
    #include <signal.h>

    #include <iostream>
    #include <string>
    #include <chrono>
    #include <bobcat/fork>
    #include <bobcat/semaphore>
    #include <bobcat/sharedsegment>
    #include <bobcat/sharedmutex>

    using namespace std;
    using namespace FBB;

    class Wait: public Fork
    {
        SharedSegment *d_shared;
        int d_id;
        SharedMutex *d_mutex;

        public:
            Wait();
            ~Wait();
            void childProcess() override;
            void parentProcess() override;
    };

    Wait::Wait()
    :
        d_shared(SharedSegment::create(&d_id, 1, 100, 0700)),
        d_mutex(new (d_shared) SharedMutex)
    {
        cout << "shared memory ID = " << d_id << '\n';
    }

    Wait::~Wait()
    {
        d_mutex->~SharedMutex();
        SharedSegment::deleteSegment(d_id);
        cout << "deleted the shared memory\n";
    }

    void Wait::childProcess()
    {
        Semaphore waiter{0};

        while (true)
        {
            waiter.wait_for(chrono::seconds(2));
            d_mutex->lock();
            cout << "child hello\n";
            d_mutex->unlock();
        }
    }

    void Wait::parentProcess()
    {
        string line;
        do
        {
            cout << "press enter to allow the parent to locck\n";
            cin.ignore(100, '\n');
            d_mutex->lock();
            cout << "parent has the lock, press enter to continue "
                    "(to end: some input)\n";
            getline(cin, line);
            d_mutex->unlock();
        }
        while (line.empty());

        kill(pid(), SIGTERM);
    }

    int main()
    {
        Wait waiter;
        waiter.fork();
    }

## FILES

bobcat/sharedmutex - defines the class interface

## SEE ALSO

bobcat(7) isharedstream(3bobcat), osharedstream(3bobcat), sharedblock(3bobcat), sharedcondition(3bobcat), sharedmemory(3bobcat), (e.g.,) pthread_mutex_init(3posix), sharedpos(3bobcat), sharedreadme(7bobcat), sharedsegment(3bobcat), sharedstream(3bobcat), sharedbuf(3bobcat)

## BUGS

None Reported.

## BOBCAT PROJECT FILES

- https://fbb-git.gitlab.io/bobcat/: gitlab project page;
- bobcat_6.06.02-x.dsc: detached signature;
- bobcat_6.06.02-x.tar.gz: source archive;
- bobcat_6.06.02-x_i386.changes: change log;
- libbobcat1_6.06.02-x_*.deb: debian package containing the libraries;
- libbobcat1-dev_6.06.02-x_*.deb: debian package containing the libraries, headers and manual pages;

## BOBCAT

Bobcat is an acronym of `Brokken's Own Base Classes And Templates'.

## COPYRIGHT

This is free software, distributed under the terms of the GNU General Public License (GPL).

## AUTHOR

Frank B. Brokken (f.b.brokken@rug.nl).