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>
34 void Semaphore::Remove(const std::string &fileName)
36 if (sem_unlink(fileName.c_str()) == -1) {
38 LogPedantic("Failed to unlink semaphore. Errno: " << error);
39 ThrowMsg(Exception::RemoveFailed,
40 "Failed to unlink semaphore. Errno: " << error);
44 Semaphore::Semaphore(size_t maxLockCount)
46 LogPedantic("Allocating unnamed semaphore:");
47 LogPedantic(" Maximum lock count: " << maxLockCount);
49 if (-1 == sem_init(&m_semaphore.unnamed.handle,
51 static_cast<unsigned>(maxLockCount)))
55 LogPedantic("Failed to create semaphore. Errno: " << error);
57 ThrowMsg(Exception::CreateFailed,
58 "Failed to create semaphore. Errno: " << error);
61 m_type = Type_Unnamed;
64 Semaphore::Semaphore(const std::string &fileName,
71 LogPedantic("Allocating named semaphore:");
72 LogPedantic(" File name: " << fileName);
73 LogPedantic(" Maximum lock count: " << maxLockCount);
74 LogPedantic(" File name: " << fileName);
75 LogPedantic(" Allowed create: " << allowCreate);
76 LogPedantic(" Exclusive create: " << exclusiveCreate);
77 LogPedantic(" Permissions: " << permissions);
78 LogPedantic(" Unlink on destroy: " << unlinkOnDestroy);
88 semaphore = sem_open(fileName.c_str(),
91 static_cast<unsigned>(maxLockCount));
95 semaphore = sem_open(fileName.c_str(),
98 static_cast<unsigned>(maxLockCount));
103 semaphore = sem_open(fileName.c_str(), 0);
106 while (semaphore == SEM_FAILED && errno == EINTR);
108 if (semaphore == SEM_FAILED)
112 LogPedantic("Failed to create semaphore '" << fileName
113 << "'. Errno: " << error);
115 ThrowMsg(Exception::CreateFailed,
116 "Failed to create semaphore '" << fileName
117 << "'. Errno: " << error);
120 m_semaphore.named.handle = semaphore;
122 m_semaphore.named.name = strdup(fileName.c_str()); // May be NULL
124 if (m_semaphore.named.name == NULL)
125 LogPedantic("Out of memory while duplicating semaphore name");
127 m_semaphore.named.unlinkOnDestroy = unlinkOnDestroy;
132 Semaphore::~Semaphore()
137 sem_t *Semaphore::InternalGet() const
142 return &m_semaphore.unnamed.handle;
145 return m_semaphore.named.handle;
148 Assert(false && "Invalid type");
154 void Semaphore::InternalDestroy()
159 if (sem_destroy(&m_semaphore.unnamed.handle) == -1)
163 LogPedantic("Failed to destroy semaphore. Errno: " << error);
168 if (sem_close(m_semaphore.named.handle) == -1)
172 LogPedantic("Failed to close semaphore. Errno: " << error);
175 if (m_semaphore.named.name != NULL)
177 // Unlink named semaphore
178 if (m_semaphore.named.unlinkOnDestroy &&
179 sem_unlink(m_semaphore.named.name) == -1)
183 LogPedantic("Failed to unlink semaphore. Errno: "
188 free(m_semaphore.named.name);
193 Assert(false && "Invalid type");
197 void Semaphore::Lock() const
199 if (TEMP_FAILURE_RETRY(sem_wait(InternalGet())) != 0)
203 LogPedantic("Failed to lock semaphore. Errno: " << error);
205 ThrowMsg(Exception::LockFailed,
206 "Failed to lock semaphore. Errno: " << error);
210 void Semaphore::Unlock() const
212 if (sem_post(InternalGet()) != 0)
216 LogPedantic("Failed to unlock semaphore. Errno: " << error);
218 ThrowMsg(Exception::UnlockFailed,
219 "Failed to unlock semaphore. Errno: " << error);
223 Semaphore::ScopedLock::ScopedLock(Semaphore *semaphore)
224 : m_semaphore(semaphore)
226 Assert(semaphore != NULL);
230 Semaphore::ScopedLock::~ScopedLock()
234 m_semaphore->Unlock();
236 Catch (Semaphore::Exception::UnlockFailed)
238 LogPedantic("Failed to leave semaphore scoped lock");