2 * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 * @author Przemyslaw Dobrowolski (p.dobrowolsk@samsung.com)
20 * @brief This file is the implementation file of semaphore
23 #include <dpl/semaphore.h>
24 #include <dpl/assert.h>
25 #include <dpl/log/log.h>
33 void Semaphore::Remove(const std::string &fileName)
35 if (sem_unlink(fileName.c_str()) == -1) {
37 LogPedantic("Failed to unlink semaphore. Errno: " << error);
38 ThrowMsg(Exception::RemoveFailed,
39 "Failed to unlink semaphore. Errno: " << error);
43 Semaphore::Semaphore(size_t maxLockCount)
45 LogPedantic("Allocating unnamed semaphore:");
46 LogPedantic(" Maximum lock count: " << maxLockCount);
48 if (-1 == sem_init(&m_semaphore.unnamed.handle,
50 static_cast<unsigned>(maxLockCount)))
54 LogPedantic("Failed to create semaphore. Errno: " << error);
56 ThrowMsg(Exception::CreateFailed,
57 "Failed to create semaphore. Errno: " << error);
60 m_type = Type_Unnamed;
63 Semaphore::Semaphore(const std::string &fileName,
70 LogPedantic("Allocating named semaphore:");
71 LogPedantic(" File name: " << fileName);
72 LogPedantic(" Maximum lock count: " << maxLockCount);
73 LogPedantic(" File name: " << fileName);
74 LogPedantic(" Allowed create: " << allowCreate);
75 LogPedantic(" Exclusive create: " << exclusiveCreate);
76 LogPedantic(" Permissions: " << permissions);
77 LogPedantic(" Unlink on destroy: " << unlinkOnDestroy);
83 if (exclusiveCreate) {
84 semaphore = sem_open(fileName.c_str(),
87 static_cast<unsigned>(maxLockCount));
89 semaphore = sem_open(fileName.c_str(),
92 static_cast<unsigned>(maxLockCount));
95 semaphore = sem_open(fileName.c_str(), 0);
97 } while (semaphore == SEM_FAILED && errno == EINTR);
99 if (semaphore == SEM_FAILED) {
102 LogPedantic("Failed to create semaphore '" << fileName
103 << "'. Errno: " << error);
105 ThrowMsg(Exception::CreateFailed,
106 "Failed to create semaphore '" << fileName
107 << "'. Errno: " << error);
110 m_semaphore.named.handle = semaphore;
112 m_semaphore.named.name = strdup(fileName.c_str()); // May be NULL
114 if (m_semaphore.named.name == NULL) {
115 LogPedantic("Out of memory while duplicating semaphore name");
118 m_semaphore.named.unlinkOnDestroy = unlinkOnDestroy;
123 Semaphore::~Semaphore()
128 sem_t *Semaphore::InternalGet() const
132 return &m_semaphore.unnamed.handle;
135 return m_semaphore.named.handle;
138 Assert(false && "Invalid type");
144 void Semaphore::InternalDestroy()
148 if (sem_destroy(&m_semaphore.unnamed.handle) == -1) {
151 LogPedantic("Failed to destroy semaphore. Errno: " << error);
156 if (sem_close(m_semaphore.named.handle) == -1) {
159 LogPedantic("Failed to close semaphore. Errno: " << error);
162 if (m_semaphore.named.name != NULL) {
163 // Unlink named semaphore
164 if (m_semaphore.named.unlinkOnDestroy &&
165 sem_unlink(m_semaphore.named.name) == -1)
169 LogPedantic("Failed to unlink semaphore. Errno: "
174 free(m_semaphore.named.name);
179 Assert(false && "Invalid type");
183 void Semaphore::Lock() const
185 if (TEMP_FAILURE_RETRY(sem_wait(InternalGet())) != 0) {
188 LogPedantic("Failed to lock semaphore. Errno: " << error);
190 ThrowMsg(Exception::LockFailed,
191 "Failed to lock semaphore. Errno: " << error);
195 void Semaphore::Unlock() const
197 if (sem_post(InternalGet()) != 0) {
200 LogPedantic("Failed to unlock semaphore. Errno: " << error);
202 ThrowMsg(Exception::UnlockFailed,
203 "Failed to unlock semaphore. Errno: " << error);
207 Semaphore::ScopedLock::ScopedLock(Semaphore *semaphore) :
208 m_semaphore(semaphore)
210 Assert(semaphore != NULL);
214 Semaphore::ScopedLock::~ScopedLock()
218 m_semaphore->Unlock();
220 Catch(Semaphore::Exception::UnlockFailed)
222 LogPedantic("Failed to leave semaphore scoped lock");