From ea76b6988ccafaa6a4d4ed90f2489d0e49e1f180 Mon Sep 17 00:00:00 2001 From: Benjamin Barenblat Date: Sat, 5 Sep 2015 09:32:30 -0400 Subject: Imported Upstream version 0.40.24 --- g_src/mail.hpp | 155 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 155 insertions(+) create mode 100755 g_src/mail.hpp (limited to 'g_src/mail.hpp') diff --git a/g_src/mail.hpp b/g_src/mail.hpp new file mode 100755 index 0000000..b158e31 --- /dev/null +++ b/g_src/mail.hpp @@ -0,0 +1,155 @@ +#ifndef MAIL_H +#define MAIL_H + +#include +#include +#include + +template +class MBox { + T val; + SDL_sem *fill, *empty; +public: + bool try_read(T &r) { // Attempt to read the mbox. Returns true if read succeeded. + if (SDL_SemTryWait(fill) == 0) { + r = val; + SDL_SemPost(empty); + return true; + } else + return false; + } + void read(T &r) { + SDL_SemWait(fill); + r = val; + SDL_SemPost(empty); + } + void write(const T &v) { + SDL_SemWait(empty); + val = v; + SDL_SemPost(fill); + } + bool try_write(const T &v) { // Returns true if the write succeeded + if (SDL_SemTryWait(empty) == 0) { + val = v; + SDL_SemPost(fill); + return true; + } else + return false; + } + MBox(T &v) { + MBox(); + write(v); + } + MBox() { + fill = SDL_CreateSemaphore(0); + empty = SDL_CreateSemaphore(1); + } + ~MBox() { + SDL_DestroySemaphore(fill); + SDL_DestroySemaphore(empty); + } +}; + +template +class MVar { + SDL_sem *s; +public: + T val; + void lock() { SDL_SemWait(s); } + void unlock() { SDL_SemPost(s); } + MVar() { s = SDL_CreateSemaphore(1); } + ~MVar() { SDL_DestroySemaphore(s); } + void write(const T &w) { lock(); val = w; unlock(); } + void read(T &r) { lock(); r = val; unlock(); } + T read() { T r; read(r); return r; } +}; + + +template +class Lock { + SDL_sem *s; +public: + void lock() { SDL_SemWait(s); } + void unlock() { SDL_SemPost(s); } + Lock() { s = SDL_CreateSemaphore(start_locked ? 0 : 1); } + ~Lock() { SDL_DestroySemaphore(s); } +}; + + +template +class Chan { + MVar > vals; + SDL_sem *fill; +public: + bool try_read(T &r) { + if (SDL_SemTryWait(fill) == 0) { + vals.lock(); + r = vals.val.front(); + vals.val.pop(); + vals.unlock(); + return true; + } else + return false; + } + void read(T &r) { + SDL_SemWait(fill); + vals.lock(); + r = vals.val.front(); + vals.val.pop(); + vals.unlock(); + } + void write(const T &w) { + vals.lock(); + vals.val.push(w); + vals.unlock(); + SDL_SemPost(fill); + } + Chan() { + fill = SDL_CreateSemaphore(0); + } + ~Chan() { + SDL_DestroySemaphore(fill); + } +}; + +template<> +class Chan { + SDL_sem *fill; +public: + bool try_read() { + if (SDL_SemTryWait(fill) == 0) + return true; + return false; + } + void read() { + SDL_SemWait(fill); + } + void write() { + SDL_SemPost(fill); + } + Chan() { + fill = SDL_CreateSemaphore(0); + } + ~Chan() { + SDL_DestroySemaphore(fill); + } +}; + +template +struct Either { + bool isL; + union { + L left; + R right; + }; + Either(const L &l) { + isL = true; + left = l; + } + Either(const R &r) { + isL = false; + right = r; + } +}; + +#endif -- cgit v1.2.3