summaryrefslogtreecommitdiff
path: root/ACE/ace/Reverse_Lock_T.h
blob: 571deb0de85285605f2276635e96b681c378b01c (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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
// -*- C++ -*-

//==========================================================================
/**
 *  @file    Reverse_Lock_T.h
 *
 *   Moved from Synch.h.
 *
 *  @author Douglas C. Schmidt <d.schmidt@vanderbilt.edu>
 */
//==========================================================================

#ifndef ACE_REVERSE_LOCK_T_H
#define ACE_REVERSE_LOCK_T_H
#include /**/ "ace/pre.h"

#include "ace/Lock.h"

#if !defined (ACE_LACKS_PRAGMA_ONCE)
# pragma once
#endif /* ACE_LACKS_PRAGMA_ONCE */

ACE_BEGIN_VERSIONED_NAMESPACE_DECL

/**
 * @namespace ACE_Acquire_Method
 *
 * @brief An enum namespace.
 *
 * These enums should have been inside the reverse lock class, but
 * some lame compilers cannot handle enums inside template classes.
 *
 * The METHOD_TYPE is used to indicate which acquire() method will be
 * called on the real lock when the release() method is called on the
 * reverse lock. REGULAR indicated the acquire() method, READ
 * indicates the acquire_read() method, and WRITE indicates the
 * acquire_write() method.  Note that the try_*() methods are not
 * represented here because we have to make sure that the release()
 * method on the reverse lock acquires a lock on the real lock.
 **/
namespace ACE_Acquire_Method
{
  enum METHOD_TYPE
  {
    ACE_REGULAR,
    ACE_READ,
    ACE_WRITE
  };
}

/**
 * @class ACE_Reverse_Lock
 *
 * @brief A reverse (or anti) lock.
 *
 * This is an interesting adapter class that changes a lock into
 * a reverse lock, i.e., <acquire> on this class calls <release>
 * on the lock, and <release> on this class calls <acquire> on
 * the lock.
 * One motivation for this class is when we temporarily want to
 * release a lock (which we have already acquired) but then
 * reacquire it soon after.  An alternative design would be to
 * add a Anti_Guard or Reverse_Guard class which would <release>
 * on construction and <acquire> destruction.  However, there
 * are *many* varieties of the Guard class and this design
 * choice would lead to at least 6 new classes.  One new
 * ACE_Reverse_Lock class seemed more reasonable.
 */
template <class ACE_LOCKING_MECHANISM>
class ACE_Reverse_Lock : public ACE_Lock
{
public:

  typedef ACE_LOCKING_MECHANISM ACE_LOCK;

  // = Initialization/Finalization methods.

  /// Constructor. All locking requests will be forwarded to @a lock.
  ACE_Reverse_Lock (ACE_LOCKING_MECHANISM &lock,
                    ACE_Acquire_Method::METHOD_TYPE acquire_method = ACE_Acquire_Method::ACE_REGULAR);

  /// Destructor. If <lock_> was not passed in by the user, it will be
  /// deleted.
  virtual ~ACE_Reverse_Lock ();

  // = Lock accessors.
  /// Release the lock.
  virtual int acquire ();

  /// Release the lock.
  virtual int tryacquire ();

  /// Acquire the lock.
  virtual int release ();

  /// Release the lock.
  virtual int acquire_read ();

  /// Release the lock.
  virtual int acquire_write ();

  /// Release the lock.
  virtual int tryacquire_read ();

  /// Release the lock.
  virtual int tryacquire_write ();

  /// Release the lock.
  virtual int tryacquire_write_upgrade ();

  /// Explicitly destroy the lock.
  virtual int remove ();

private:
  /// The concrete locking mechanism that all the methods delegate to.
  ACE_LOCKING_MECHANISM &lock_;

  /// This indicates what kind of acquire method will be called.
  ACE_Acquire_Method::METHOD_TYPE acquire_method_;
};

ACE_END_VERSIONED_NAMESPACE_DECL

#if defined (__ACE_INLINE__)
#include "ace/Reverse_Lock_T.inl"
#endif /* __ACE_INLINE__ */

#if defined (ACE_TEMPLATES_REQUIRE_SOURCE)
#include "ace/Reverse_Lock_T.cpp"
#endif /* ACE_TEMPLATES_REQUIRE_SOURCE */

#if defined (ACE_TEMPLATES_REQUIRE_PRAGMA)
#pragma implementation ("Reverse_Lock_T.cpp")
#endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */

#include /**/ "ace/post.h"
#endif /* ACE_REVERSE_LOCK_T_H */