Fix race between killing object and drawing object
[lsnes.git] / include / library / workthread.hpp
blobcf5ec9b82d3c26590b4d75c86f02e0e2e0bf1ec9
1 #ifndef _library_workthread__hpp__included__
2 #define _library_workthread__hpp__included__
4 #include <cstdint>
5 #include "threads.hpp"
7 /**
8 * A worker thread.
10 * Note: All methods (except entrypoints) are thread-safe.
12 class workthread
14 public:
15 /**
16 * Standard quit request.
18 static const uint32_t quit_request;
19 /**
20 * Constructor.
22 workthread();
23 /**
24 * Destructor.
26 virtual ~workthread();
27 /**
28 * Request quit. Sets quit request workflag.
30 void request_quit();
31 /**
32 * Set the busy flag.
34 void set_busy();
35 /**
36 * Clear the busy flag.
38 void clear_busy();
39 /**
40 * Wait until busy flag cleared.
42 void wait_busy();
43 /**
44 * Rethrow caught exception if any.
46 void rethrow();
47 /**
48 * Set work flag.
50 * Parameter flag: The flags to set.
52 void set_workflag(uint32_t flag);
53 /**
54 * Clear work flag.
56 * Parameter flag: Work flags to clear.
57 * Returns: The workflags before clearing.
59 uint32_t clear_workflag(uint32_t flag);
60 /**
61 * Wait until work flags nonzero.
63 * Returns: Current work flags.
65 uint32_t wait_workflag();
66 /**
67 * Thread raw entrypoint.
69 * Note: Don't call from outside workthread code.
71 int operator()(int dummy);
72 /**
73 * Get wait counters.
75 * Retrns: Two-element tuple.
76 * - The first element is the amount of microseconds wait_busy() has waited.
77 * - The second element is the amount of microseconds wait_workflag() has waited.
79 std::pair<uint64_t, uint64_t> get_wait_count();
80 protected:
81 /**
82 * Thread entrypoint.
84 * Notes: Exceptions thrown are catched.
86 virtual void entry() = 0;
87 /**
88 * Start actually running the thread.
90 void fire();
91 private:
92 threads::thread* thread;
93 struct reflector
95 int operator()(workthread* x);
97 reflector* _reflector;
98 threads::cv condition;
99 threads::lock mlock;
100 volatile bool joined;
101 volatile uint32_t workflag;
102 volatile bool busy;
103 volatile bool exception_caught;
104 volatile bool exception_oom;
105 volatile uint64_t waitamt_busy;
106 volatile uint64_t waitamt_work;
107 std::string exception_text;
110 #endif