Merge pull request #2301 from sonndinh/remove-dup-reactor-functions
[ACE_TAO.git] / ACE / ace / SV_Semaphore_Simple.cpp
blobc5b904e63de1331dc5fc6459737bcb3bd968d24f
1 #include "ace/SV_Semaphore_Simple.h"
2 #include "ace/Log_Category.h"
3 #include "ace/ACE.h"
4 #include "ace/os_include/sys/os_sem.h"
5 #if defined (ACE_HAS_ALLOC_HOOKS)
6 # include "ace/Malloc_Base.h"
7 #endif /* ACE_HAS_ALLOC_HOOKS */
9 #if !defined (__ACE_INLINE__)
10 #include "ace/SV_Semaphore_Simple.inl"
11 #endif /* !__ACE_INLINE__ */
13 ACE_BEGIN_VERSIONED_NAMESPACE_DECL
15 ACE_ALLOC_HOOK_DEFINE (ACE_SV_Semaphore_Simple)
17 void
18 ACE_SV_Semaphore_Simple::dump () const
20 #if defined (ACE_HAS_DUMP)
21 ACE_TRACE ("ACE_SV_Semaphore_Simple::dump");
22 #endif /* ACE_HAS_DUMP */
25 int
26 ACE_SV_Semaphore_Simple::control (int cmd,
27 int value,
28 u_short semnum) const
30 ACE_TRACE ("ACE_SV_Semaphore_Simple::control");
31 if (this->internal_id_ == -1)
32 return -1;
33 else
35 semun semctl_arg;
37 semctl_arg.val = value;
38 return ACE_OS::semctl (this->internal_id_,
39 semnum,
40 cmd,
41 semctl_arg);
45 #ifdef ACE_HAS_SYSV_IPC
46 int
47 ACE_SV_Semaphore_Simple::init (key_t k, int i)
49 ACE_TRACE ("ACE_SV_Semaphore_Simple::init");
50 this->key_ = k;
51 this->internal_id_ = i;
52 return 0;
54 #endif
56 // General ACE_SV_Semaphore operation. Increment or decrement by a
57 // specific amount (positive or negative; amount can`t be zero).
59 int
60 ACE_SV_Semaphore_Simple::op (short val, u_short n, short flags) const
62 ACE_TRACE ("ACE_SV_Semaphore_Simple::op");
63 sembuf op_op;
65 op_op.sem_num = n;
66 op_op.sem_flg = flags;
68 if (this->internal_id_ == -1)
69 return -1;
70 else if ((op_op.sem_op = val) == 0)
71 return -1;
72 else
73 return ACE_OS::semop (this->internal_id_, &op_op, 1);
76 // Open or create one or more SV_Semaphores. We return 0 if all is
77 // OK, else -1.
79 int
80 ACE_SV_Semaphore_Simple::open (key_t k,
81 short flags,
82 int initial_value,
83 u_short n,
84 mode_t perms)
86 ACE_TRACE ("ACE_SV_Semaphore_Simple::open");
87 union semun ivalue;
89 #ifdef ACE_HAS_SYSV_IPC
90 if (k == IPC_PRIVATE || k == static_cast<key_t> (ACE_INVALID_SEM_KEY))
91 return -1;
92 #endif
94 ivalue.val = initial_value;
95 this->key_ = k;
96 this->sem_number_ = n;
98 this->internal_id_ = ACE_OS::semget (this->key_, n, perms | flags);
100 if (this->internal_id_ == -1)
101 return -1;
103 if (ACE_BIT_ENABLED (flags, IPC_CREAT))
104 for (int i = 0; i < n; i++)
105 if (ACE_OS::semctl (this->internal_id_, i, SETVAL, ivalue) == -1)
106 return -1;
108 return 0;
111 ACE_SV_Semaphore_Simple::ACE_SV_Semaphore_Simple (key_t k,
112 short flags,
113 int initial_value,
114 u_short n,
115 mode_t perms)
116 : key_ (k)
118 ACE_TRACE ("ACE_SV_Semaphore_Simple::ACE_SV_Semaphore_Simple");
119 if (this->open (k, flags, initial_value, n, perms) == -1)
120 ACELIB_ERROR ((LM_ERROR, ACE_TEXT ("%p\n"), ACE_TEXT ("ACE_SV_Semaphore::ACE_SV_Semaphore")));
123 // Convert name to key. This function is used internally to create keys
124 // for the semaphores.
126 // The method for generating names is a 32 bit CRC, but still we
127 // measured close to collition ratio of nearly 0.1% for
128 // ACE::unique_name()-like strings.
130 key_t
131 ACE_SV_Semaphore_Simple::name_2_key (const char *name)
133 ACE_TRACE ("ACE_SV_Semaphore_Simple::name_2_key");
135 if (name == 0)
137 errno = EINVAL;
138 #ifdef ACE_HAS_SYSV_IPC
139 return static_cast<key_t> (ACE_INVALID_SEM_KEY);
140 #else
141 key_t ret = ACE_DEFAULT_SEM_KEY;
142 return ret;
143 #endif
146 // Basically "hash" the values in the <name>. This won't
147 // necessarily guarantee uniqueness of all keys.
148 // But (IMHO) CRC32 is good enough for most purposes (Carlos)
149 #if defined (ACE_WIN32) && defined (_MSC_VER)
150 // The cast below is legit...
151 # pragma warning(push)
152 # pragma warning(disable : 4312)
153 #endif /* defined (ACE_WIN32) && defined (_MSC_VER) */
155 #ifdef ACE_HAS_SYSV_IPC
156 return (key_t) ACE::crc32 (name);
157 #else
158 key_t ret = ACE_DEFAULT_SEM_KEY;
159 return ret;
160 #endif
162 #if defined (ACE_WIN32) && defined (_MSC_VER)
163 # pragma warning(pop)
164 #endif /* defined (ACE_WIN32) && defined (_MSC_VER) */
167 // Open or create a ACE_SV_Semaphore. We return 1 if all is OK, else
168 // 0.
171 ACE_SV_Semaphore_Simple::open (const char *name,
172 short flags,
173 int initial_value,
174 u_short n,
175 mode_t perms)
177 ACE_TRACE ("ACE_SV_Semaphore_Simple::open");
179 key_t key = ACE_DEFAULT_SEM_KEY;
181 #ifdef ACE_HAS_SYSV_IPC
182 if (name != 0)
183 key = this->name_2_key (name);
184 #else
185 ACE_UNUSED_ARG (name);
186 #endif
188 return this->open (key, flags, initial_value, n, perms);
191 ACE_SV_Semaphore_Simple::ACE_SV_Semaphore_Simple (const char *name,
192 short flags,
193 int initial_value,
194 u_short n,
195 mode_t perms)
197 ACE_TRACE ("ACE_SV_Semaphore_Simple::ACE_SV_Semaphore_Simple");
198 if (this->open (name,
199 flags,
200 initial_value,
202 perms) == -1)
203 ACELIB_ERROR ((LM_ERROR,
204 ACE_TEXT ("%p\n"),
205 ACE_TEXT ("ACE_SV_Semaphore_Simple::ACE_SV_Semaphore_Simple")));
208 #if defined (ACE_HAS_WCHAR)
209 ACE_SV_Semaphore_Simple::ACE_SV_Semaphore_Simple (const wchar_t *name,
210 short flags,
211 int initial_value,
212 u_short nsems,
213 mode_t perms)
215 ACE_TRACE ("ACE_SV_Semaphore_Simple::ACE_SV_Semaphore_Simple(wchar_t)");
216 if (this->open (ACE_Wide_To_Ascii (name).char_rep (),
217 flags,
218 initial_value,
219 nsems,
220 perms) == -1)
221 ACELIB_ERROR ((LM_ERROR,
222 ACE_TEXT ("%p\n"),
223 ACE_TEXT ("ACE_SV_Semaphore_Simple::ACE_SV_Semaphore_Simple")));
225 #endif /* ACE_HAS_WCHAR */
227 ACE_SV_Semaphore_Simple::~ACE_SV_Semaphore_Simple ()
229 ACE_TRACE ("ACE_SV_Semaphore_Simple::~ACE_SV_Semaphore_Simple");
230 this->close ();
233 ACE_SV_Semaphore_Simple::ACE_SV_Semaphore_Simple () :
234 sem_number_ (0)
236 ACE_TRACE ("ACE_SV_Semaphore_Simple::ACE_SV_Semaphore_Simple");
237 #ifdef ACE_HAS_SYSV_IPC
238 this->init ();
239 #endif
242 // Remove all SV_Semaphores associated with a particular key. This
243 // call is intended to be called from a server, for example, when it
244 // is being shut down, as we do an IPC_RMID on the ACE_SV_Semaphore,
245 // regardless of whether other processes may be using it or not. Most
246 // other processes should use close() below.
249 ACE_SV_Semaphore_Simple::remove () const
251 ACE_TRACE ("ACE_SV_Semaphore_Simple::remove");
252 int const result = this->control (IPC_RMID);
253 #ifdef ACE_HAS_SYSV_IPC
254 ((ACE_SV_Semaphore_Simple *) this)->init ();
255 #endif
256 return result;
259 ACE_END_VERSIONED_NAMESPACE_DECL