You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
@@ -58,16 +66,21 @@ class IAsyncQueueDispatcherBase
58
66
assert(prev==ES_EXECUTING);
59
67
state.notify_one();
60
68
}
69
+
70
+
// non-blocking query
71
+
boolis_ready() const
72
+
{
73
+
return state.load()==ES_READY;
74
+
}
61
75
// to call to await the request to finish processing
62
-
voidwait_ready()
76
+
voidwait_ready()const
63
77
{
64
78
wait_for(ES_READY);
65
79
}
66
80
// to call after done reading the request and its memory can be recycled
67
81
voiddiscard_storage()
68
82
{
69
-
constauto prev = state.exchange(ES_INITIAL);
70
-
assert(prev==ES_READY);
83
+
transition(ES_READY,ES_INITIAL);
71
84
state.notify_one();
72
85
}
73
86
@@ -82,7 +95,7 @@ class IAsyncQueueDispatcherBase
82
95
}
83
96
assert(expected==from);
84
97
}
85
-
voidwait_for(const E_STATE waitVal)
98
+
voidwait_for(const E_STATE waitVal)const
86
99
{
87
100
uint32_t current;
88
101
while ((current=state.load())!=waitVal)
@@ -95,11 +108,21 @@ class IAsyncQueueDispatcherBase
95
108
}
96
109
97
110
/**
111
+
* Required accessible methods of class being CRTP parameter:
112
+
*
113
+
* void init(internal_state_t* state); // required only in case of custom internal state
114
+
*
115
+
* void exit(internal_state_t* state); // optional, no `state` parameter in case of no internal state
116
+
*
117
+
* void request_impl(request_t& req, ...); // `...` are parameteres forwarded from request(), the request's state is locked with a mutex during the call
118
+
* void process_request(request_t& req, internal_state_t& state); // no `state` parameter in case of no internal state
119
+
* void background_work() // optional, does nothing if not provided
120
+
*
121
+
*
98
122
* Provided RequestType shall define 5 methods:
99
-
* T reset();
100
-
* void finalize(T&&);
123
+
* void start();
124
+
* void finalize();
101
125
* T wait_for_work();
102
-
* T wait_for_result();
103
126
* T notify_all_ready(T&&);
104
127
* TODO: [outdated docs] lock() will be called just before processing the request, and unlock() will be called just after processing the request.
105
128
* Those are to enable safe external write access to the request struct for user-defined purposes.
@@ -110,18 +133,20 @@ class IAsyncQueueDispatcherBase
110
133
* notify_all_ready() takes an r-value reference to an already locked mutex and notifies any waiters then releases the lock
// maybe one day we'll abstract this into a lockless queue
125
150
usingatomic_counter_t = std::atomic_uint64_t;
126
151
usingcounter_t = atomic_counter_t::value_type;
127
152
@@ -135,11 +160,9 @@ class IAsyncQueueDispatcher : public IThreadHandler<CRTP, InternalStateType>, pu
135
160
return x & Mask;
136
161
}
137
162
138
-
139
163
public:
140
-
141
-
IAsyncQueueDispatcher() {};
142
-
~IAsyncQueueDispatcher() {};
164
+
inlineIAsyncQueueDispatcher() {}
165
+
inline~IAsyncQueueDispatcher() {}
143
166
144
167
usingmutex_t = typenamebase_t::mutex_t;
145
168
usinglock_t = typenamebase_t::lock_t;
@@ -148,20 +171,10 @@ class IAsyncQueueDispatcher : public IThreadHandler<CRTP, InternalStateType>, pu
148
171
149
172
usingrequest_t = RequestType;
150
173
151
-
///////
152
-
// Required accessible methods of class being CRTP parameter:
153
-
154
-
//void init(internal_state_t* state); // required only in case of custom internal state
155
-
156
-
//void exit(internal_state_t* state); // optional, no `state` parameter in case of no internal state
157
-
158
-
//void request_impl(request_t& req, ...); // `...` are parameteres forwarded from request(), the request's state is locked with a mutex during the call
159
-
//void process_request(request_t& req, internal_state_t& state); // no `state` parameter in case of no internal state
160
-
//void background_work() // optional, does nothing if not provided
161
-
///////
162
-
163
-
usingbase_t::base_t;
164
-
174
+
// Returns a reference to a request's storage in the circular buffer after processing the moved arguments
175
+
// YOU MUST CONSUME THE REQUEST by calling `discard_storage()` on it EXACTLY ONCE!
176
+
// YOU MUST CALL IT EVEN IF THERE'S NO DATA YOU WISH TO GET BACK FROM IT!
177
+
// (if you don't the queue will deadlock because of an unresolved overflow)
165
178
template <typename... Args>
166
179
request_t& request(Args&&... args)
167
180
{
@@ -174,7 +187,7 @@ class IAsyncQueueDispatcher : public IThreadHandler<CRTP, InternalStateType>, pu
0 commit comments