Skip to content

Commit

Permalink
Split semaphore.cpp file
Browse files Browse the repository at this point in the history
  • Loading branch information
gammasoft71 committed Jul 31, 2023
1 parent 33c8301 commit 280c099
Show file tree
Hide file tree
Showing 5 changed files with 151 additions and 6 deletions.
3 changes: 3 additions & 0 deletions src/xtd.core/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -864,10 +864,13 @@ add_sources(
src/xtd/threading/mutex.cpp
src/xtd/threading/mutex_base.h
src/xtd/threading/named_mutex.h
src/xtd/threading/named_semaphore.h
src/xtd/threading/semaphore.cpp
src/xtd/threading/semaphore_base.h
src/xtd/threading/thread.cpp
src/xtd/threading/timeout.cpp
src/xtd/threading/unnamed_mutex.h
src/xtd/threading/unnamed_semaphore.h
src/xtd/threading/wait_handle.cpp
src/xtd/environment.cpp # Must be the last file to be compiled, as the std::atexit method must be the first to be called before static variables are destroyed.
)
Expand Down
53 changes: 53 additions & 0 deletions src/xtd.core/src/xtd/threading/named_semaphore.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#prafma once
#include "../../../include/xtd/threading/semaphore.h"
#define __XTD_CORE_NATIVE_LIBRARY__
#include <xtd/native/named_semaphore.h>
#undef __XTD_CORE_NATIVE_LIBRARY__

class xtd::threading::semaphore::named_semaphore : public semaphore_base {
public:
~named_semaphore() {destroy();}

intptr handle() const noexcept override {
return handle_;
}

void handle(intptr value) override {
handle_ = value;
}

bool create(int32 initial_count, int32 maximum_count) override {
throw invalid_operation_exception {csf_};
}

bool create(int32 initial_count, int32 maximum_count, const ustring& name) override {
name_ = name;
handle_ = native::named_semaphore::create(initial_count, maximum_count, name);
return handle_ != invalid_handle;
}

void destroy() override {
if (handle_ == invalid_handle) return;
native::named_semaphore::destroy(handle_, name_);
handle_ = invalid_handle;
}

bool open(const ustring& name) override {
name_ = name;
handle_ = native::named_semaphore::open(name);
return handle_ != invalid_handle;
}

bool signal(bool& io_error, int32 release_count, int32& previous_count) override {
io_error = false;
return native::named_semaphore::signal(handle_, release_count, previous_count, io_error);
}

uint32 wait(int32 milliseconds_timeout) override {
return native::named_semaphore::wait(handle_, milliseconds_timeout);
}

private:
intptr handle_ = invalid_handle;
ustring name_;
};
8 changes: 2 additions & 6 deletions src/xtd.core/src/xtd/threading/semaphore.cpp
Original file line number Diff line number Diff line change
@@ -1,15 +1,11 @@
#include "../../../include/xtd/threading/semaphore.h"
#include "named_semaphore.h"
#include "unnamed_semaphore.h"
#include "../../../include/xtd/argument_out_of_range_exception.h"
#include "../../../include/xtd/object_closed_exception.h"
#include "../../../include/xtd/invalid_operation_exception.h"
#include "../../../include/xtd/io/io_exception.h"
#include "../../../include/xtd/io/path_too_long_exception.h"
#include "../../../include/xtd/threading/abandoned_mutex_exception.h"
#define __XTD_CORE_NATIVE_LIBRARY__
#include <xtd/native/named_semaphore.h>
#undef __XTD_CORE_NATIVE_LIBRARY__
#include <condition_variable>
#include <mutex>

using namespace xtd;
using namespace xtd::threading;
Expand Down
16 changes: 16 additions & 0 deletions src/xtd.core/src/xtd/threading/semaphore_base.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#pragma once
#include "../../../include/xtd/threading/semaphore.h"

class xtd::threading::semaphore::semaphore_base {
public:
virtual ~semaphore_base() = default;

virtual intptr handle() const noexcept = 0;
virtual void handle(intptr value) = 0;
virtual bool create(int32 initial_count, int32 maximum_count) = 0;
virtual bool create(int32 initial_count, int32 maximum_count, const ustring& name) = 0;
virtual void destroy() = 0;
virtual bool open(const ustring& name) = 0;
virtual bool signal(bool& io_error, int32 release_count, int32& previous_count) = 0;
virtual uint32 wait(int32 milliseconds_timeout) = 0;
};
77 changes: 77 additions & 0 deletions src/xtd.core/src/xtd/threading/unnamed_semaphore.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
#pragma once
#include "../../../include/xtd/threading/semaphore.h"
#include <condition_variable>
#include <mutex>

class xtd::threading::semaphore::unnamed_semaphore : public semaphore_base {
public:
~unnamed_semaphore() {destroy();}

intptr handle() const noexcept override {
return handle_ ? reinterpret_cast<intptr>(handle_.get()) : invalid_handle;
}

void handle(intptr value) override {
throw invalid_operation_exception {csf_};
}

bool create(int32 initial_count, int32 maximum_count) override {
handle_ = std::make_shared<data>();
handle_->maximum_count = maximum_count;
uint32 error = 0;
for (auto index = 0; !error && index < initial_count; ++index)
error = wait(-1);
if (error) return false;
return true;
}

bool create(int32 initial_count, int32 maximum_count, const ustring& name) override {
throw invalid_operation_exception {csf_};
}

void destroy() override {
if (!handle_) return;
handle_.reset();
}

bool open(const ustring& name) override {
throw invalid_operation_exception {csf_};
}

bool signal(bool& io_error, int32 release_count, int32& previous_count) override {
std::unique_lock<std::mutex> lock(handle_->mutex);
previous_count = handle_->count;
for (int count = 0; count < release_count; ++count) {
if (handle_->count + 1 >= handle_->maximum_count) {
io_error = true;
return false;
}
handle_->count++;
handle_->condition.notify_one();
}
return true;
}

uint32 wait(int32 milliseconds_timeout) override {
std::unique_lock<std::mutex> lock(handle_->mutex);
if (handle_->count == 0) return 0xFFFFFFFF;

if (milliseconds_timeout == -1) {
handle_->condition.wait(lock);
handle_->count--;
return 0x00000000;
}
if (handle_->condition.wait_for(lock, std::chrono::milliseconds {milliseconds_timeout}) == std::cv_status::timeout) return 0x00000102;
handle_->count--;
return 0x00000000;
}

private:
struct data {
std::condition_variable condition;
int count = 0;
int maximum_count = std::numeric_limits<int>::max();
std::mutex mutex;
};
std::shared_ptr<data> handle_;
};

0 comments on commit 280c099

Please sign in to comment.