diff options
author | Jef <jef@targetspot.com> | 2024-09-24 08:54:57 -0400 |
---|---|---|
committer | Jef <jef@targetspot.com> | 2024-09-24 08:54:57 -0400 |
commit | 20d28e80a5c861a9d5f449ea911ab75b4f37ad0d (patch) | |
tree | 12f17f78986871dd2cfb0a56e5e93b545c1ae0d0 /Src/nu/ThreadQueue.cpp | |
parent | 537bcbc86291b32fc04ae4133ce4d7cac8ebe9a7 (diff) | |
download | winamp-20d28e80a5c861a9d5f449ea911ab75b4f37ad0d.tar.gz |
Initial community commit
Diffstat (limited to 'Src/nu/ThreadQueue.cpp')
-rw-r--r-- | Src/nu/ThreadQueue.cpp | 66 |
1 files changed, 66 insertions, 0 deletions
diff --git a/Src/nu/ThreadQueue.cpp b/Src/nu/ThreadQueue.cpp new file mode 100644 index 00000000..34def11f --- /dev/null +++ b/Src/nu/ThreadQueue.cpp @@ -0,0 +1,66 @@ + #include "ThreadQueue.h" +#include <assert.h> +#include <time.h> + +static inline __attribute__((always_inline)) +void get_exceed_time(struct timespec* ptime, long delay) +{ + clock_gettime(CLOCK_REALTIME, ptime); + + ptime->tv_nsec += delay; + if (ptime->tv_nsec >= 1000000000L) // overflow + { + ptime->tv_nsec -= 1000000000L; + ++ptime->tv_sec; + } +} + +ThreadQueue::ThreadQueue() +{ + buffer.reserve(256 * sizeof(void *)); + sem_init(&event, 0, 0); +} + +ThreadQueue::~ThreadQueue() +{ + sem_destroy(&event); +} + +void ThreadQueue::Queue(const void *in) +{ + buffer.write(&in, sizeof(in)); + sem_post(&event); +} + +void *ThreadQueue::Get() +{ + sem_wait(&event); + void *out=0; + size_t read = buffer.read(&out, sizeof(out)); + assert(read == sizeof(out)); + return out; +} + +int ThreadQueue::Wait(long delay, void **val) +{ + timespec t; + get_exceed_time(&t, delay); + int ret = sem_timedwait(&event, &t); + if (ret == 0) + { + size_t read = buffer.read(val, sizeof(*val)); + assert(read == sizeof(*val)); + } + return ret; +} + +int ThreadQueue::Try(void **val) +{ + int ret = sem_trywait(&event); + if (ret == 0) + { + size_t read = buffer.read(val, sizeof(*val)); + assert(read == sizeof(*val)); + } + return ret; +} |