squall/storm/thread/SSyncObject.cpp

166 lines
3.7 KiB
C++
Raw Permalink Normal View History

2020-11-01 17:45:45 -06:00
#include "storm/thread/SSyncObject.hpp"
2020-09-09 00:45:46 -05:00
2020-12-02 20:04:02 -06:00
#if defined(WHOA_SYSTEM_MAC) || defined(WHOA_SYSTEM_LINUX)
2020-09-09 00:45:46 -05:00
#include <cerrno>
#include <sys/time.h>
#include <unistd.h>
#endif
SSyncObject::SSyncObject() {
2020-12-02 20:04:02 -06:00
#if defined(WHOA_SYSTEM_MAC) || defined(WHOA_SYSTEM_LINUX)
2020-09-09 00:45:46 -05:00
pthread_mutex_init(&this->m_mutex, 0);
#endif
}
SSyncObject::~SSyncObject() {
#if defined(WHOA_SYSTEM_WIN)
this->Close();
#endif
#if defined(WHOA_SYSTEM_MAC) || defined(WHOA_SYSTEM_LINUX)
pthread_mutex_destroy(&this->m_mutex);
#endif
}
void SSyncObject::Close() {
#if defined(WHOA_SYSTEM_WIN)
if (this->m_opaqueData) {
CloseHandle(this->m_opaqueData);
this->m_opaqueData = nullptr;
}
#endif
}
2022-10-16 15:09:56 -05:00
bool SSyncObject::Valid() {
#if defined(WHOA_SYSTEM_WIN)
return this->m_opaqueData != nullptr;
#endif
#if defined(WHOA_SYSTEM_MAC) || defined(WHOA_SYSTEM_LINUX)
return this->int0 - 1 <= 4;
#endif
}
2020-09-09 00:45:46 -05:00
uint32_t SSyncObject::Wait(uint32_t timeoutMs) {
2020-12-02 20:04:02 -06:00
#if defined(WHOA_SYSTEM_WIN)
2020-09-09 00:45:46 -05:00
return WaitForSingleObject(this->m_opaqueData, timeoutMs);
#endif
2020-12-02 20:04:02 -06:00
#if defined(WHOA_SYSTEM_MAC) || defined(WHOA_SYSTEM_LINUX)
if (this->int0 == 6) {
2020-09-09 00:45:46 -05:00
// WAIT_FAILED
return 0xFFFFFFFF;
}
if (timeoutMs != 0xFFFFFFFF) {
timeval v10;
timespec v11;
if (timeoutMs) {
gettimeofday(&v10, nullptr);
v11.tv_sec = v10.tv_sec + timeoutMs / 1000;
uint32_t v7 = 1000 * v10.tv_usec + 1000000 * (timeoutMs % 1000);
v11.tv_nsec = v7;
if (v7 > 999999999) {
v11.tv_sec = v10.tv_sec + timeoutMs / 1000 + 1;
v11.tv_nsec = v7 - 1000000000;
}
} else {
v11.tv_sec = 0;
v11.tv_nsec = 0;
}
while (true) {
int32_t v3 = pthread_mutex_trylock(&this->m_mutex);
if (!v3) {
break;
}
if (v3 != EBUSY) {
if (v3 != ETIMEDOUT) {
// WAIT_FAILED
return 0xFFFFFFFF;
} else {
// WAIT_TIMEOUT
return 0x00000102;
}
}
gettimeofday(&v10, nullptr);
if (v10.tv_sec > v11.tv_sec || (v10.tv_sec == v11.tv_sec && 1000 * v10.tv_usec >= v11.tv_nsec)) {
// WAIT_TIMEOUT
return 0x00000102;
}
usleep(0);
}
if (this->int0 == 3) {
2020-09-09 00:45:46 -05:00
// WAIT_OBJECT_0
return 0;
}
int32_t v4;
while (true) {
v4 = this->m_value1;
2020-09-09 00:45:46 -05:00
if (v4) {
break;
}
int32_t v5 = pthread_cond_timedwait(&this->m_cond, &this->m_mutex, &v11);
if (v5) {
pthread_mutex_unlock(&this->m_mutex);
if (v5 == ETIMEDOUT) {
// WAIT_TIMEOUT
return 0x00000102;
} else {
// WAIT_FAILED
return 0xFFFFFFFF;
}
}
}
if (this->int0 == 2) {
this->m_value1 = 0;
} else if (this->int0 == 4) {
this->m_value1 = v4 - 1;
2020-09-09 00:45:46 -05:00
}
pthread_mutex_unlock(&this->m_mutex);
// WAIT_OBJECT_0
return 0;
}
pthread_mutex_lock(&this->m_mutex);
if (this->int0 == 3) {
2020-09-09 00:45:46 -05:00
// WAIT_OBJECT_0
return 0;
}
while (!this->m_value1) {
2020-09-09 00:45:46 -05:00
pthread_cond_wait(&this->m_cond, &this->m_mutex);
}
if (this->int0 == 2) {
this->m_value1 = 0;
} else if (this->int0 == 4) {
this->m_value1 = this->m_value1 - 1;
2020-09-09 00:45:46 -05:00
}
pthread_mutex_unlock(&this->m_mutex);
// WAIT_OBJECT_0
return 0;
#endif
}