1 #include "ace/SV_Semaphore_Simple.h"
2 #include "ace/Log_Category.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
)
18 ACE_SV_Semaphore_Simple::dump (void) const
20 #if defined (ACE_HAS_DUMP)
21 ACE_TRACE ("ACE_SV_Semaphore_Simple::dump");
22 #endif /* ACE_HAS_DUMP */
26 ACE_SV_Semaphore_Simple::control (int cmd
,
30 ACE_TRACE ("ACE_SV_Semaphore_Simple::control");
31 if (this->internal_id_
== -1)
37 semctl_arg
.val
= value
;
38 return ACE_OS::semctl (this->internal_id_
,
45 #ifdef ACE_HAS_SYSV_IPC
47 ACE_SV_Semaphore_Simple::init (key_t k
, int i
)
49 ACE_TRACE ("ACE_SV_Semaphore_Simple::init");
51 this->internal_id_
= i
;
56 // General ACE_SV_Semaphore operation. Increment or decrement by a
57 // specific amount (positive or negative; amount can`t be zero).
60 ACE_SV_Semaphore_Simple::op (short val
, u_short n
, short flags
) const
62 ACE_TRACE ("ACE_SV_Semaphore_Simple::op");
66 op_op
.sem_flg
= flags
;
68 if (this->internal_id_
== -1)
70 else if ((op_op
.sem_op
= val
) == 0)
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
80 ACE_SV_Semaphore_Simple::open (key_t k
,
86 ACE_TRACE ("ACE_SV_Semaphore_Simple::open");
89 #ifdef ACE_HAS_SYSV_IPC
90 if (k
== IPC_PRIVATE
|| k
== static_cast<key_t
> (ACE_INVALID_SEM_KEY
))
94 ivalue
.val
= initial_value
;
96 this->sem_number_
= n
;
98 this->internal_id_
= ACE_OS::semget (this->key_
, n
, perms
| flags
);
100 if (this->internal_id_
== -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)
111 ACE_SV_Semaphore_Simple::ACE_SV_Semaphore_Simple (key_t 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.
131 ACE_SV_Semaphore_Simple::name_2_key (const char *name
)
133 ACE_TRACE ("ACE_SV_Semaphore_Simple::name_2_key");
138 #ifdef ACE_HAS_SYSV_IPC
139 return static_cast<key_t
> (ACE_INVALID_SEM_KEY
);
141 key_t ret
= ACE_DEFAULT_SEM_KEY
;
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
);
158 key_t ret
= ACE_DEFAULT_SEM_KEY
;
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
171 ACE_SV_Semaphore_Simple::open (const char *name
,
177 ACE_TRACE ("ACE_SV_Semaphore_Simple::open");
179 key_t key
= ACE_DEFAULT_SEM_KEY
;
181 #ifdef ACE_HAS_SYSV_IPC
183 key
= this->name_2_key (name
);
185 ACE_UNUSED_ARG (name
);
188 return this->open (key
, flags
, initial_value
, n
, perms
);
191 ACE_SV_Semaphore_Simple::ACE_SV_Semaphore_Simple (const char *name
,
197 ACE_TRACE ("ACE_SV_Semaphore_Simple::ACE_SV_Semaphore_Simple");
198 if (this->open (name
,
203 ACELIB_ERROR ((LM_ERROR
,
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
,
215 ACE_TRACE ("ACE_SV_Semaphore_Simple::ACE_SV_Semaphore_Simple(wchar_t)");
216 if (this->open (ACE_Wide_To_Ascii (name
).char_rep (),
221 ACELIB_ERROR ((LM_ERROR
,
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 (void)
229 ACE_TRACE ("ACE_SV_Semaphore_Simple::~ACE_SV_Semaphore_Simple");
233 ACE_SV_Semaphore_Simple::ACE_SV_Semaphore_Simple (void) :
236 ACE_TRACE ("ACE_SV_Semaphore_Simple::ACE_SV_Semaphore_Simple");
237 #ifdef ACE_HAS_SYSV_IPC
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 (void) 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 ();
259 ACE_END_VERSIONED_NAMESPACE_DECL