First commit.
This commit is contained in:
163
src/System/Semaphore_P.cpp
Normal file
163
src/System/Semaphore_P.cpp
Normal file
@@ -0,0 +1,163 @@
|
||||
#include "../../include/System/Semaphore_P.h"
|
||||
#include "../../include/Log.h"
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <cerrno>
|
||||
|
||||
namespace lwe
|
||||
{
|
||||
Semaphore::~Semaphore()
|
||||
{
|
||||
if (!Semaphore::IsValid())
|
||||
return;
|
||||
|
||||
if (sem_destroy(&hdl) == -1)
|
||||
LWE_LOG_INT("Error", 0, "Failed to release semaphore with error #" + Str_8::FromNum(errno) + ".");
|
||||
|
||||
valid = false;
|
||||
}
|
||||
|
||||
Semaphore::Semaphore()
|
||||
: hdl{}, valid(false)
|
||||
{
|
||||
}
|
||||
|
||||
Semaphore::Semaphore(const Str_8& name, const UInt_32 initial)
|
||||
: BaseSemaphore(name, initial), hdl{}, valid(false)
|
||||
{
|
||||
Semaphore::Initialize();
|
||||
}
|
||||
|
||||
Semaphore::Semaphore(const UInt_32 initial)
|
||||
: BaseSemaphore(initial), hdl{}, valid(false)
|
||||
{
|
||||
Semaphore::Initialize();
|
||||
}
|
||||
|
||||
Semaphore::Semaphore(Semaphore&& sem) noexcept
|
||||
: BaseSemaphore((Semaphore&&)sem), hdl(sem.hdl), valid(sem.valid)
|
||||
{
|
||||
sem.hdl = {};
|
||||
sem.valid = false;
|
||||
}
|
||||
|
||||
Semaphore::Semaphore(const Semaphore& sem)
|
||||
: BaseSemaphore(sem), hdl{}, valid(false)
|
||||
{
|
||||
Semaphore::Initialize();
|
||||
}
|
||||
|
||||
Semaphore& Semaphore::operator=(Semaphore&& sem) noexcept
|
||||
{
|
||||
if (this == &sem)
|
||||
return *this;
|
||||
|
||||
Release();
|
||||
|
||||
BaseSemaphore::operator=((Semaphore&&)sem);
|
||||
|
||||
hdl = sem.hdl;
|
||||
valid = sem.valid;
|
||||
|
||||
sem.hdl = {};
|
||||
sem.valid = false;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
Semaphore& Semaphore::operator=(const Semaphore& sem)
|
||||
{
|
||||
if (this == &sem)
|
||||
return *this;
|
||||
|
||||
Release();
|
||||
|
||||
BaseSemaphore::operator=(sem);
|
||||
|
||||
hdl = {};
|
||||
valid = false;
|
||||
|
||||
Initialize();
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
void Semaphore::Initialize()
|
||||
{
|
||||
if (IsValid())
|
||||
return;
|
||||
|
||||
if (GetName().Size())
|
||||
{
|
||||
sem_t* result = sem_open("/" + GetName(), O_CREAT | O_EXCL, S_IRUSR | S_IWUSR, GetInitial());
|
||||
if (!result)
|
||||
LWE_LOG_INT("Error", 0, "Failed to create semaphore with error #" + Str_8::FromNum(errno) + ".");
|
||||
|
||||
hdl = *result;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (sem_init(&hdl, 0, GetInitial()) == -1)
|
||||
LWE_LOG_INT("Error", 0, "Failed to create semaphore with error #" + Str_8::FromNum(errno) + ".");
|
||||
}
|
||||
|
||||
valid = true;
|
||||
}
|
||||
|
||||
void Semaphore::Release()
|
||||
{
|
||||
if (!IsValid())
|
||||
return;
|
||||
|
||||
if (sem_destroy(&hdl) == -1)
|
||||
LWE_LOG_INT("Error", 0, "Failed to release semaphore with error #" + Str_8::FromNum(errno) + ".");
|
||||
|
||||
hdl = {};
|
||||
|
||||
valid = false;
|
||||
}
|
||||
|
||||
void Semaphore::Signal(const UInt_32 inc)
|
||||
{
|
||||
if (!IsValid())
|
||||
return;
|
||||
|
||||
if (sem_post(&hdl) == -1)
|
||||
LWE_LOG_INT("Error", 0, "Failed to signal semaphore with error #" + Str_8::FromNum(errno) + ".");
|
||||
}
|
||||
|
||||
bool Semaphore::Wait(const UInt_32 timeout)
|
||||
{
|
||||
if (!IsValid())
|
||||
return false;
|
||||
|
||||
int result;
|
||||
|
||||
if (timeout == LWE_INFINITE)
|
||||
{
|
||||
result = sem_wait(&hdl);
|
||||
}
|
||||
else
|
||||
{
|
||||
timespec time = {timeout / 1000, timeout % 1000 * 1000000};
|
||||
result = sem_timedwait(&hdl, &time);
|
||||
}
|
||||
|
||||
if (result == -1)
|
||||
{
|
||||
int code = errno;
|
||||
if (code != ETIMEDOUT)
|
||||
LWE_LOG_INT("Error", 0, "Failed to wait for semaphore with error #" + Str_8::FromNum(errno) + ".");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Semaphore::IsValid() const
|
||||
{
|
||||
return valid;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user