1 #include "RNSkDispatchQueue.h" 2 3 #include <memory> 4 #include <mutex> 5 #include <utility> 6 7 namespace RNSkia 8 { 9 ~RNSkDispatchQueue()10 RNSkDispatchQueue::~RNSkDispatchQueue() 11 { 12 // Signal to dispatch threads that it's time to wrap up 13 std::unique_lock<std::mutex> lock(lock_); 14 quit_ = true; 15 lock.unlock(); 16 cv_.notify_all(); 17 18 // Wait for threads to finish before we exit 19 for (size_t i = 0; i < threads_.size(); i++) 20 { 21 if (threads_[i].joinable()) 22 { 23 threads_[i].join(); 24 } 25 } 26 } 27 RNSkDispatchQueue(std::string name,size_t thread_cnt)28 RNSkDispatchQueue::RNSkDispatchQueue(std::string name, size_t thread_cnt) 29 : name_{std::move(name)}, threads_(thread_cnt) 30 { 31 for (size_t i = 0; i < threads_.size(); i++) 32 { 33 threads_[i] = std::thread(&RNSkDispatchQueue::dispatch_thread_handler, this); 34 } 35 } 36 dispatch(const fp_t & op)37 void RNSkDispatchQueue::dispatch(const fp_t &op) 38 { 39 std::unique_lock<std::mutex> lock(lock_); 40 q_.push(op); 41 42 // Manual unlocking is done before notifying, to avoid waking up 43 // the waiting thread only to block again (see notify_one for details) 44 lock.unlock(); 45 cv_.notify_one(); 46 } 47 dispatch(fp_t && op)48 void RNSkDispatchQueue::dispatch(fp_t &&op) 49 { 50 std::unique_lock<std::mutex> lock(lock_); 51 q_.push(std::move(op)); 52 53 // Manual unlocking is done before notifying, to avoid waking up 54 // the waiting thread only to block again (see notify_one for details) 55 lock.unlock(); 56 cv_.notify_one(); 57 } 58 dispatch_thread_handler(void)59 void RNSkDispatchQueue::dispatch_thread_handler(void) 60 { 61 std::unique_lock<std::mutex> lock(lock_); 62 63 do 64 { 65 // Wait until we have data or a quit signal 66 cv_.wait(lock, [this] 67 { return (q_.size() || quit_); }); 68 69 // after wait, we own the lock 70 if (!quit_ && q_.size()) 71 { 72 auto op = std::move(q_.front()); 73 q_.pop(); 74 75 // unlock now that we're done messing with the queue 76 lock.unlock(); 77 78 op(); 79 80 lock.lock(); 81 } 82 } while (!quit_); 83 } 84 } // namespace RNSkia 85