aboutsummaryrefslogtreecommitdiff
path: root/Src/nu/ThreadQueue.cpp
diff options
context:
space:
mode:
authorJef <jef@targetspot.com>2024-09-24 08:54:57 -0400
committerJef <jef@targetspot.com>2024-09-24 08:54:57 -0400
commit20d28e80a5c861a9d5f449ea911ab75b4f37ad0d (patch)
tree12f17f78986871dd2cfb0a56e5e93b545c1ae0d0 /Src/nu/ThreadQueue.cpp
parent537bcbc86291b32fc04ae4133ce4d7cac8ebe9a7 (diff)
downloadwinamp-20d28e80a5c861a9d5f449ea911ab75b4f37ad0d.tar.gz
Initial community commit
Diffstat (limited to 'Src/nu/ThreadQueue.cpp')
-rw-r--r--Src/nu/ThreadQueue.cpp66
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;
+}