mirror of
https://github.com/86Box/86Box.git
synced 2025-01-23 17:52:01 -05:00
137 lines
2.7 KiB
C++
137 lines
2.7 KiB
C++
#include <mutex>
|
|
#include <thread>
|
|
#include <condition_variable>
|
|
|
|
#include <86box/plat.h>
|
|
#include <86box/thread.h>
|
|
|
|
struct event_cpp11_t {
|
|
std::condition_variable cond;
|
|
std::mutex mutex;
|
|
bool state = false;
|
|
};
|
|
|
|
extern "C" {
|
|
|
|
thread_t *
|
|
thread_create_named(void (*thread_rout)(void *param), void *param, const char *name)
|
|
{
|
|
auto thread = new std::thread([thread_rout, param, name] {
|
|
plat_set_thread_name(NULL, name);
|
|
thread_rout(param);
|
|
});
|
|
return thread;
|
|
}
|
|
|
|
int
|
|
thread_wait(thread_t *arg)
|
|
{
|
|
if (!arg)
|
|
return 0;
|
|
auto thread = reinterpret_cast<std::thread *>(arg);
|
|
thread->join();
|
|
return 0;
|
|
}
|
|
|
|
mutex_t *
|
|
thread_create_mutex(void)
|
|
{
|
|
auto mutex = new std::mutex;
|
|
return mutex;
|
|
}
|
|
|
|
int
|
|
thread_test_mutex(mutex_t *_mutex)
|
|
{
|
|
if (_mutex == nullptr)
|
|
return 0;
|
|
|
|
auto mutex = reinterpret_cast<std::mutex *>(_mutex);
|
|
return mutex->try_lock() ? 1 : 0;
|
|
}
|
|
|
|
int
|
|
thread_wait_mutex(mutex_t *_mutex)
|
|
{
|
|
if (_mutex == nullptr)
|
|
return 0;
|
|
|
|
auto mutex = reinterpret_cast<std::mutex *>(_mutex);
|
|
mutex->lock();
|
|
return 1;
|
|
}
|
|
|
|
int
|
|
thread_release_mutex(mutex_t *_mutex)
|
|
{
|
|
if (_mutex == nullptr)
|
|
return 0;
|
|
|
|
auto mutex = reinterpret_cast<std::mutex *>(_mutex);
|
|
mutex->unlock();
|
|
return 1;
|
|
}
|
|
|
|
void
|
|
thread_close_mutex(mutex_t *_mutex)
|
|
{
|
|
auto mutex = reinterpret_cast<std::mutex *>(_mutex);
|
|
delete mutex;
|
|
}
|
|
|
|
event_t *
|
|
thread_create_event()
|
|
{
|
|
auto ev = new event_cpp11_t;
|
|
return ev;
|
|
}
|
|
|
|
int
|
|
thread_wait_event(event_t *handle, int timeout)
|
|
{
|
|
auto event = reinterpret_cast<event_cpp11_t *>(handle);
|
|
auto lock = std::unique_lock<std::mutex>(event->mutex);
|
|
|
|
if (timeout < 0) {
|
|
event->cond.wait(lock, [event] { return event->state; });
|
|
} else {
|
|
auto to = std::chrono::system_clock::now() + std::chrono::milliseconds(timeout);
|
|
std::cv_status status;
|
|
|
|
do {
|
|
status = event->cond.wait_until(lock, to);
|
|
} while ((status != std::cv_status::timeout) && !event->state);
|
|
|
|
if (status == std::cv_status::timeout) {
|
|
return 1;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
void
|
|
thread_set_event(event_t *handle)
|
|
{
|
|
auto event = reinterpret_cast<event_cpp11_t *>(handle);
|
|
{
|
|
auto lock = std::unique_lock<std::mutex>(event->mutex);
|
|
event->state = true;
|
|
}
|
|
event->cond.notify_all();
|
|
}
|
|
|
|
void
|
|
thread_reset_event(event_t *handle)
|
|
{
|
|
auto event = reinterpret_cast<event_cpp11_t *>(handle);
|
|
auto lock = std::unique_lock<std::mutex>(event->mutex);
|
|
event->state = false;
|
|
}
|
|
|
|
void
|
|
thread_destroy_event(event_t *handle)
|
|
{
|
|
auto event = reinterpret_cast<event_cpp11_t *>(handle);
|
|
delete event;
|
|
}
|
|
}
|