]> git.sesse.net Git - bmusb/commitdiff
Add support for stopping the dequeue thread.
authorSteinar H. Gunderson <sgunderson@bigfoot.com>
Mon, 12 Oct 2015 19:27:47 +0000 (21:27 +0200)
committerSteinar H. Gunderson <sgunderson@bigfoot.com>
Mon, 12 Oct 2015 19:27:47 +0000 (21:27 +0200)
bmusb.cpp
bmusb.h

index b2de56f2b2cee588bc4a1c01252ffa2154045a48..1079f2aa60932197799855c5b683470223a8c4ad 100644 (file)
--- a/bmusb.cpp
+++ b/bmusb.cpp
@@ -144,14 +144,14 @@ void dump_audio_block(uint8_t *audio_start, size_t audio_len)
        fwrite(audio_start + AUDIO_HEADER_SIZE, 1, audio_len - AUDIO_HEADER_SIZE, audiofp);
 }
 
-void BMUSBCapture::dequeue_thread()
+void BMUSBCapture::dequeue_thread_func()
 {
        if (has_dequeue_callbacks) {
                dequeue_init_callback();
        }
-       for ( ;; ) {
+       while (!dequeue_thread_should_quit) {
                unique_lock<mutex> lock(queue_lock);
-               queues_not_empty.wait(lock, [this]{ return !pending_video_frames.empty() && !pending_audio_frames.empty(); });
+               queues_not_empty.wait(lock, [this]{ return dequeue_thread_should_quit || (!pending_video_frames.empty() && !pending_audio_frames.empty()); });
 
                uint16_t video_timecode = pending_video_frames.front().timecode;
                uint16_t audio_timecode = pending_audio_frames.front().timecode;
@@ -634,7 +634,8 @@ void BMUSBCapture::configure_card()
        if (audio_frame_allocator == nullptr) {
                set_audio_frame_allocator(new MallocFrameAllocator(65536));  // FIXME: leak.
        }
-       thread(&BMUSBCapture::dequeue_thread, this).detach();
+       dequeue_thread_should_quit = false;
+       dequeue_thread = thread(&BMUSBCapture::dequeue_thread_func, this);
 
        int rc;
        struct libusb_transfer *xfr;
@@ -937,6 +938,13 @@ out:
 #endif
 }
 
+void BMUSBCapture::stop_dequeue_thread()
+{
+       dequeue_thread_should_quit = true;
+       queues_not_empty.notify_all();
+       dequeue_thread.join();
+}
+
 void BMUSBCapture::start_bm_thread()
 {
        should_quit = false;
diff --git a/bmusb.h b/bmusb.h
index c7a5224d4ad31a41f5846123dc363a8be4c3fd46..96a2257f8549279dc0000c7b31dfb2df8709e62a 100644 (file)
--- a/bmusb.h
+++ b/bmusb.h
@@ -105,6 +105,7 @@ class BMUSBCapture {
 
        void configure_card();
        void start_bm_capture();
+       void stop_dequeue_thread();
 
        static void start_bm_thread();
        static void stop_bm_thread();
@@ -120,7 +121,7 @@ class BMUSBCapture {
        void start_new_frame(const uint8_t *start);
 
        void queue_frame(uint16_t format, uint16_t timecode, FrameAllocator::Frame frame, std::deque<QueuedFrame> *q);
-       void dequeue_thread();
+       void dequeue_thread_func();
 
        static void usb_thread_func();
        static void cb_xfr(struct libusb_transfer *xfr);
@@ -137,6 +138,8 @@ class BMUSBCapture {
        FrameAllocator *audio_frame_allocator = nullptr;
        frame_callback_t frame_callback = nullptr;
 
+       std::thread dequeue_thread;
+       std::atomic<bool> dequeue_thread_should_quit;
        bool has_dequeue_callbacks = false;
        std::function<void()> dequeue_init_callback = nullptr;
        std::function<void()> dequeue_cleanup_callback = nullptr;