summaryrefslogtreecommitdiff
path: root/ACE/ace/Process_Semaphore.h
blob: 1024d70b6da3162918a7576b135554166888749a (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
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
// -*- C++ -*-

//=============================================================================
/**
 *  @file    Process_Semaphore.h
 *
 *   Wrapper for Dijkstra style general semaphores that work
 *   across processes.
 *
 *  @author Douglas C. Schmidt <d.schmidt@vanderbilt.edu>
 */
//=============================================================================

#ifndef ACE_PROCESS_SEMAPHORE_H
#define ACE_PROCESS_SEMAPHORE_H

#include /**/ "ace/pre.h"

#include /**/ "ace/ACE_export.h"

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

#if !(defined (ACE_WIN32) || defined (ACE_HAS_POSIX_SEM))
# include "ace/SV_Semaphore_Complex.h"
#else
# include "ace/Semaphore.h"
#endif /* !(ACE_WIN32 || ACE_HAS_POSIX_SEM) */

ACE_BEGIN_VERSIONED_NAMESPACE_DECL

/**
 * @class ACE_Process_Semaphore
 *
 * @brief Wrapper for Dijkstra style general semaphores that work
 * across processes.
 */
class ACE_Export ACE_Process_Semaphore
{
public:
  /// Initialize the semaphore, with an initial value of @a count and a
  /// maximum value of @a max.
  ACE_Process_Semaphore (u_int count = 1, // By default make this unlocked.
                         const ACE_TCHAR *name = 0,
                         void * = 0,
                         int max = 0x7FFFFFFF);

  /**
   * Explicitly destroy the semaphore.  Note that only one thread
   * should call this method since it doesn't protect against race
   * conditions.
   */
  int remove (void);

  /// Block the thread until the semaphore count becomes greater than
  /// 0, then decrement it.
  int acquire (void);

  /**
   * Conditionally decrement the semaphore if count is greater than 0
   * (i.e., won't block).  Returns -1 on failure.  If we "failed"
   * because someone else already had the lock, @c errno is set to
   * @c EBUSY.
   */
  int tryacquire (void);

  /// Increment the semaphore, potentially unblocking a waiting thread.
  int release (void);

  /**
   * Acquire semaphore ownership.  This calls acquire() and is only
   * here to make the ACE_Process_Semaphore interface consistent
   * with the other synchronization APIs.
   */
  int acquire_read (void);

  /**
   * Acquire semaphore ownership.  This calls acquire() and is only
   * here to make the ACE_Process_Semaphore interface consistent
   * with the other synchronization APIs.
   */
  int acquire_write (void);

  /**
   * Conditionally acquire semaphore (i.e., won't block).  This calls
   * tryacquire() and is only here to make the ACE_Process_Semaphore
   * interface consistent with the other synchronization APIs.
   * Returns -1 on failure.  If we "failed" because someone else
   * already had the lock, @c errno is set to @c EBUSY.
   */
  int tryacquire_read (void);

  /**
   * Conditionally acquire semaphore (i.e., won't block).  This calls
   * tryacquire() and is only here to make the ACE_Process_Semaphore
   * interface consistent with the other synchronization APIs.
   * Returns -1 on failure.  If we "failed" because someone else
   * already had the lock, @c errno is set to @c EBUSY.
   */
  int tryacquire_write (void);

  /**
   * This is only here to make the ACE_Process_Semaphore
   * interface consistent with the other synchronization APIs.
   * Assumes the caller has already acquired the semaphore using one of
   * the above calls, and returns 0 (success) always.
   */
  int tryacquire_write_upgrade (void);

#if defined (ACE_WIN32) || defined (ACE_HAS_POSIX_SEM)
  /// Return the underlying lock.
  const ACE_sema_t &lock (void) const;
#endif /* ACE_WIN32 || ACE_HAS_POSIX_SEM */

  /// Dump the state of an object.
  void dump () const;

  /// Declare the dynamic allocation hooks.
  ACE_ALLOC_HOOK_DECLARE;

protected:
#if defined (ACE_WIN32) || defined (ACE_HAS_POSIX_SEM)
  ACE_Semaphore lock_;
#else
  /// We need this to get the right semantics...
  ACE_SV_Semaphore_Complex lock_;
#endif /* ACE_WIN32 || ACE_HAS_POSIX_SEM */
};

/*****************************************************************************/

template <class T> class ACE_Malloc_Lock_Adapter_T;

/**
 * @brief Template specialization of ACE_Malloc_Lock_Adapter_T for
 * ACE_Process_Semaphore.
 *
 * This is needed since the constructor for ACE_Process_Semaphore doesn't match
 * the standard form used by other lock strategy classes.
 */
template<>
class ACE_Export ACE_Malloc_Lock_Adapter_T<ACE_Process_Semaphore>
{
public:
  ACE_Process_Semaphore * operator () (const ACE_TCHAR *name);
};

ACE_END_VERSIONED_NAMESPACE_DECL

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

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