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
22 #include <dpl/semaphore.h>
23 #include <dpl/assert.h>
24 #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);
87 semaphore = sem_open(fileName.c_str(),
90 static_cast<unsigned>(maxLockCount));
94 semaphore = sem_open(fileName.c_str(),
97 static_cast<unsigned>(maxLockCount));
102 semaphore = sem_open(fileName.c_str(), 0);
105 while (semaphore == SEM_FAILED && errno == EINTR);
107 if (semaphore == SEM_FAILED)
111 LogPedantic("Failed to create semaphore '" << fileName
112 << "'. Errno: " << error);
114 ThrowMsg(Exception::CreateFailed,
115 "Failed to create semaphore '" << fileName
116 << "'. Errno: " << error);
119 m_semaphore.named.handle = semaphore;
121 m_semaphore.named.name = strdup(fileName.c_str()); // May be NULL
123 if (m_semaphore.named.name == NULL)
124 LogPedantic("Out of memory while duplicating semaphore name");
126 m_semaphore.named.unlinkOnDestroy = unlinkOnDestroy;
131 Semaphore::~Semaphore()
136 sem_t *Semaphore::InternalGet() const
141 return &m_semaphore.unnamed.handle;
144 return m_semaphore.named.handle;
147 Assert(false && "Invalid type");
153 void Semaphore::InternalDestroy()
158 if (sem_destroy(&m_semaphore.unnamed.handle) == -1)
162 LogPedantic("Failed to destroy semaphore. Errno: " << error);
167 if (sem_close(m_semaphore.named.handle) == -1)
171 LogPedantic("Failed to close semaphore. Errno: " << error);
174 if (m_semaphore.named.name != NULL)
176 // Unlink named semaphore
177 if (m_semaphore.named.unlinkOnDestroy &&
178 sem_unlink(m_semaphore.named.name) == -1)
182 LogPedantic("Failed to unlink semaphore. Errno: "
187 free(m_semaphore.named.name);
192 Assert(false && "Invalid type");
196 void Semaphore::Lock() const
198 if (TEMP_FAILURE_RETRY(sem_wait(InternalGet())) != 0)
202 LogPedantic("Failed to lock semaphore. Errno: " << error);
204 ThrowMsg(Exception::LockFailed,
205 "Failed to lock semaphore. Errno: " << error);
209 void Semaphore::Unlock() const
211 if (sem_post(InternalGet()) != 0)
215 LogPedantic("Failed to unlock semaphore. Errno: " << error);
217 ThrowMsg(Exception::UnlockFailed,
218 "Failed to unlock semaphore. Errno: " << error);
222 Semaphore::ScopedLock::ScopedLock(Semaphore *semaphore)
223 : m_semaphore(semaphore)
225 Assert(semaphore != NULL);
229 Semaphore::ScopedLock::~ScopedLock()
233 m_semaphore->Unlock();
235 Catch (Semaphore::Exception::UnlockFailed)
237 LogPedantic("Failed to leave semaphore scoped lock");