aboutsummaryrefslogtreecommitdiff
path: root/works/life/operating-system-experiment/Semaphore.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'works/life/operating-system-experiment/Semaphore.cpp')
-rw-r--r--works/life/operating-system-experiment/Semaphore.cpp20
1 files changed, 20 insertions, 0 deletions
diff --git a/works/life/operating-system-experiment/Semaphore.cpp b/works/life/operating-system-experiment/Semaphore.cpp
index e8221fd..aceef4d 100644
--- a/works/life/operating-system-experiment/Semaphore.cpp
+++ b/works/life/operating-system-experiment/Semaphore.cpp
@@ -9,6 +9,8 @@
namespace cru {
Semaphore::Semaphore(unsigned init_value) {
#ifdef CRU_WINDOWS
+ handle_ = CreateSemaphoreW(nullptr, init_value, 100, nullptr);
+ assert(handle_);
#else
semaphore_ = std::make_unique<sem_t>();
auto c = sem_init(semaphore_.get(), 0, init_value);
@@ -18,16 +20,22 @@ Semaphore::Semaphore(unsigned init_value) {
Semaphore::Semaphore(Semaphore &&other)
#ifdef CRU_WINDOWS
+ : handle_(other.handle_)
#else
: semaphore_(std::move(other.semaphore_))
#endif
{
+#ifdef CRU_WINDOWS
+ other.handle_ = nullptr;
+#endif
}
Semaphore &Semaphore::operator=(Semaphore &&other) {
if (this != &other) {
Destroy();
#ifdef CRU_WINDOWS
+ handle_ = other.handle_;
+ other.handle_ = nullptr;
#else
semaphore_ = std::move(other.semaphore_);
#endif
@@ -42,6 +50,8 @@ void Semaphore::V() { Release(); }
void Semaphore::Acquire() {
#ifdef CRU_WINDOWS
+ auto c = WaitForSingleObject(handle_, INFINITE);
+ assert(c == WAIT_OBJECT_0);
#else
auto c = sem_wait(semaphore_.get());
assert(c == 0);
@@ -50,6 +60,9 @@ void Semaphore::Acquire() {
bool Semaphore::TryAcquire() {
#ifdef CRU_WINDOWS
+ auto c = WaitForSingleObject(handle_, 0);
+ assert(c == WAIT_OBJECT_0 || c == WAIT_TIMEOUT);
+ return c == WAIT_OBJECT_0 ? true : false;
#else
auto c = sem_trywait(semaphore_.get());
assert((c == 0) || (c == -1 && errno == EAGAIN));
@@ -59,6 +72,8 @@ bool Semaphore::TryAcquire() {
void Semaphore::Release() {
#ifdef CRU_WINDOWS
+ auto c = ReleaseSemaphore(handle_, 1, nullptr);
+ assert(c);
#else
auto c = sem_post(semaphore_.get());
assert(c == 0);
@@ -67,6 +82,11 @@ void Semaphore::Release() {
void Semaphore::Destroy() {
#ifdef CRU_WINDOWS
+ if (handle_ != nullptr) {
+ auto c = CloseHandle(handle_);
+ assert(c);
+ handle_ = nullptr;
+ }
#else
if (semaphore_ != nullptr) {
auto c = sem_destroy(semaphore_.get());