aboutsummaryrefslogtreecommitdiff
path: root/src/core/u_lockable.h
blob: 4e7552771240464965d20560c5241fdfaa51394c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
/******************************************************************************
* The Loki Library
* Copyright (c) 2001 by Andrei Alexandrescu
* Copyright (c) 2010-2014, Texas Instruments Incorporated
*
* This code accompanies the book:
* Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design
*     Patterns Applied". Copyright (c) 2001. Addison-Wesley.
* Permission to use, copy, modify, distribute and sell this software 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.
* The author or Addison-Wesley Longman make no representations about the
*     suitability of this software for any purpose. It is provided "as is"
*     without express or implied warranty.
******************************************************************************/

/**************************************************************************//**
*
*  @file    u_lockable.h
*
*  @brief   Defines a base class that provides a derived class with a Lock type.
*
*  @version 1.00.00
*
*  @note    The Locakable class is a modified version of the ObjectLevelLockable
*           class from the LOKI library.  The copyright from that library is
*           included at the top of this file.
*
******************************************************************************/
#ifndef _U_LOCKABLE_H_
#define _U_LOCKABLE_H_
#include "u_locks_pthread.h"

/**************************************************************************//**
* @brief used as a base class to give your derived class a Lock type.
* @details Have a class derive from this class and you can lock member
*           functions of your class by defining a lock like this
*           Lock lock(this);
******************************************************************************/
class Lockable
{
  public:
    Lockable()                : mutex() {}  //!< Default Constructor
    Lockable(const Lockable&) : mutex() {}  //!< Copy Constructor
    ~Lockable()                         {}  //!< Destructor

    /**********************************************************************//**
    * @brief The Lock type defined by inheriting from Lockable.
    **************************************************************************/
    class Lock
    {
      public:

        /*******************************************************************//**
        * @brief Constructing a Lock object will lock the parent object's mutex
        ***********************************************************************/
        explicit Lock(const Lockable* host_) : host(*host_)
                      { host.mutex.Lock();   }

        /*******************************************************************//**
        * @brief Destructing a Lock object will unlock the parent object's mutex
        ***********************************************************************/
        ~Lock()       { host.mutex.Unlock(); }

        /*******************************************************************//**
        * @brief Unlock the parent object's mutex
        ***********************************************************************/
        void unlock() { host.mutex.Unlock(); }

        /*******************************************************************//**
        * @brief Return a raw pointer to the parent object's mutex
        ***********************************************************************/
        Mutex* raw()  { return &host.mutex;  }

      private:
        const Lockable& host;       //!< a pointer back to the parent object

      private: // prevent copy construction and assignment
        Lock(const Lock&);
        Lock& operator=(const Lock&);
    };

  protected:
    mutable Mutex mutex;
};

/*-----------------------------------------------------------------------------
* Can use to turn off locking without chaning client code using Lockable
*----------------------------------------------------------------------------*/
class Lockable_off
{
  public:
    Lockable_off() {}

    class Lock
    {
      public:

        explicit Lock(const Lockable_off* host_) { }
        void unlock() { }

      private: // prevent copy construction and assignment
        Lock(const Lock&);
        Lock& operator=(const Lock&);
    };
};

#endif