@@ -107,7 +107,8 @@ class CommandQueueMT {
107107
108108 static const uint32_t DEFAULT_COMMAND_MEM_SIZE_KB = 64 ;
109109
110- bool unique_flusher = false ;
110+ inline static thread_local bool flushing = false ;
111+
111112 BinaryMutex mutex;
112113 LocalVector<uint8_t > command_mem;
113114 ConditionVariable sync_cond_var;
@@ -157,10 +158,20 @@ class CommandQueueMT {
157158 }
158159
159160 void _flush () {
161+ // Safeguard against trying to re-lock the binary mutex.
162+ if (flushing) {
163+ return ;
164+ }
165+
166+ flushing = true ;
167+
160168 MutexLock lock (mutex);
161169
162170 if (unlikely (flush_read_ptr)) {
163- // Re-entrant call.
171+ // Another thread is flushing.
172+ lock.temp_unlock (); // Not really temp.
173+ sync ();
174+ flushing = false ;
164175 return ;
165176 }
166177
@@ -177,17 +188,9 @@ class CommandQueueMT {
177188 CommandBase *cmd_local = reinterpret_cast <CommandBase *>(cmd_local_mem);
178189 memcpy (cmd_local_mem, (char *)cmd_original, size);
179190
180- if (unique_flusher) {
181- // A single thread will pump; the lock is only needed for the command queue itself.
182- lock.temp_unlock ();
183- cmd_local->call ();
184- lock.temp_relock ();
185- } else {
186- // At least we can unlock during WTP operations.
187- uint32_t allowance_id = WorkerThreadPool::thread_enter_unlock_allowance_zone (lock);
188- cmd_local->call ();
189- WorkerThreadPool::thread_exit_unlock_allowance_zone (allowance_id);
190- }
191+ lock.temp_unlock ();
192+ cmd_local->call ();
193+ lock.temp_relock ();
191194
192195 if (unlikely (cmd_local->sync )) {
193196 sync_head++;
@@ -206,6 +209,8 @@ class CommandQueueMT {
206209 flush_read_ptr = 0 ;
207210
208211 _prevent_sync_wraparound ();
212+
213+ flushing = false ;
209214 }
210215
211216 _FORCE_INLINE_ void _wait_for_sync (MutexLock<BinaryMutex> &p_lock) {
@@ -270,8 +275,7 @@ class CommandQueueMT {
270275 pump_task_id = p_task_id;
271276 }
272277
273- CommandQueueMT (bool p_unique_flusher = false ) :
274- unique_flusher (p_unique_flusher) {
278+ CommandQueueMT () {
275279 command_mem.reserve (DEFAULT_COMMAND_MEM_SIZE_KB * 1024 );
276280 }
277281};
0 commit comments