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/wrt_log.h>
33 void Semaphore::Remove(const std::string &fileName)
35 if (sem_unlink(fileName.c_str()) == -1) {
37 WrtLogD("Failed to unlink semaphore. Errno: %i", error);
38 ThrowMsg(Exception::RemoveFailed,
39 "Failed to unlink semaphore. Errno: " << error);
43 Semaphore::Semaphore(size_t maxLockCount)
45 WrtLogD("Allocating unnamed semaphore:");
46 WrtLogD(" Maximum lock count: %u", maxLockCount);
48 if (-1 == sem_init(&m_semaphore.unnamed.handle,
50 static_cast<unsigned>(maxLockCount)))
54 WrtLogD("Failed to create semaphore. Errno: %i", 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 WrtLogD("Allocating named semaphore:");
71 WrtLogD(" File name: %s", fileName.c_str());
72 WrtLogD(" Maximum lock count: %u", maxLockCount);
73 WrtLogD(" Allowed create: %s", allowCreate ? "true" : "false");
74 WrtLogD(" Exclusive create: %s", exclusiveCreate ? "true" : "false");
75 WrtLogD(" Permissions: %i", permissions);
76 WrtLogD(" Unlink on destroy: %s", unlinkOnDestroy ? "true" : "false");
82 if (exclusiveCreate) {
83 semaphore = sem_open(fileName.c_str(),
86 static_cast<unsigned>(maxLockCount));
88 semaphore = sem_open(fileName.c_str(),
91 static_cast<unsigned>(maxLockCount));
94 semaphore = sem_open(fileName.c_str(), 0);
96 } while (semaphore == SEM_FAILED && errno == EINTR);
98 if (semaphore == SEM_FAILED) {
101 WrtLogD("Failed to create semaphore '%s'. Errno: %i", fileName.c_str(), error);
103 ThrowMsg(Exception::CreateFailed,
104 "Failed to create semaphore '" << fileName
105 << "'. Errno: " << error);
108 m_semaphore.named.handle = semaphore;
110 m_semaphore.named.name = strdup(fileName.c_str()); // May be NULL
112 if (m_semaphore.named.name == NULL) {
113 WrtLogD("Out of memory while duplicating semaphore name");
116 m_semaphore.named.unlinkOnDestroy = unlinkOnDestroy;
121 Semaphore::~Semaphore()
126 sem_t *Semaphore::InternalGet() const
130 return &m_semaphore.unnamed.handle;
133 return m_semaphore.named.handle;
136 Assert(false && "Invalid type");
142 void Semaphore::InternalDestroy()
146 if (sem_destroy(&m_semaphore.unnamed.handle) == -1) {
149 WrtLogD("Failed to destroy semaphore. Errno: %i", error);
154 if (sem_close(m_semaphore.named.handle) == -1) {
157 WrtLogD("Failed to close semaphore. Errno: %i", error);
160 if (m_semaphore.named.name != NULL) {
161 // Unlink named semaphore
162 if (m_semaphore.named.unlinkOnDestroy &&
163 sem_unlink(m_semaphore.named.name) == -1)
167 WrtLogD("Failed to unlink semaphore. Errno: %i", error);
171 free(m_semaphore.named.name);
176 Assert(false && "Invalid type");
180 void Semaphore::Lock() const
182 if (TEMP_FAILURE_RETRY(sem_wait(InternalGet())) != 0) {
185 WrtLogD("Failed to lock semaphore. Errno: %i", error);
187 ThrowMsg(Exception::LockFailed,
188 "Failed to lock semaphore. Errno: " << error);
192 void Semaphore::Unlock() const
194 if (sem_post(InternalGet()) != 0) {
197 WrtLogD("Failed to unlock semaphore. Errno: %i", error);
199 ThrowMsg(Exception::UnlockFailed,
200 "Failed to unlock semaphore. Errno: " << error);
204 Semaphore::ScopedLock::ScopedLock(Semaphore *semaphore) :
205 m_semaphore(semaphore)
207 Assert(semaphore != NULL);
211 Semaphore::ScopedLock::~ScopedLock()
215 m_semaphore->Unlock();
217 Catch(Semaphore::Exception::UnlockFailed)
219 WrtLogD("Failed to leave semaphore scoped lock");