From e1c61cd2071df028d68b7ff71bde96104ac449b9 Mon Sep 17 00:00:00 2001 From: tux3 Date: Sat, 24 Oct 2015 04:38:00 +0200 Subject: [PATCH] CoreVideoSource: Replace insane spinlock by QMutex What was I thinking. --- src/video/corevideosource.cpp | 48 ++++++++++------------------------- src/video/corevideosource.h | 3 ++- 2 files changed, 15 insertions(+), 36 deletions(-) diff --git a/src/video/corevideosource.cpp b/src/video/corevideosource.cpp index 00576dff7..0a71b9b14 100644 --- a/src/video/corevideosource.cpp +++ b/src/video/corevideosource.cpp @@ -26,7 +26,7 @@ extern "C" { CoreVideoSource::CoreVideoSource() : subscribers{0}, deleteOnClose{false}, - biglock{false}, stopped{false} + stopped{false} { } @@ -35,12 +35,7 @@ void CoreVideoSource::pushFrame(const vpx_image_t* vpxframe) if (stopped) return; - // Fast lock - { - bool expected = false; - while (!biglock.compare_exchange_weak(expected, true)) - expected = false; - } + QMutexLocker locker(&biglock); std::shared_ptr vframe; AVFrame* avframe; @@ -49,11 +44,11 @@ void CoreVideoSource::pushFrame(const vpx_image_t* vpxframe) int dstStride, srcStride, minStride; if (subscribers <= 0) - goto end; + return; avframe = av_frame_alloc(); if (!avframe) - goto end; + return; avframe->width = width; avframe->height = height; avframe->format = AV_PIX_FMT_YUV420P; @@ -62,7 +57,7 @@ void CoreVideoSource::pushFrame(const vpx_image_t* vpxframe) if (!buf) { av_frame_free(&avframe); - goto end; + return; } avframe->opaque = buf; @@ -80,63 +75,46 @@ void CoreVideoSource::pushFrame(const vpx_image_t* vpxframe) vframe = std::make_shared(avframe); emit frameAvailable(vframe); - -end: - biglock = false; } bool CoreVideoSource::subscribe() { - // Fast lock - { - bool expected = false; - while (!biglock.compare_exchange_weak(expected, true)) - expected = false; - } + QMutexLocker locker(&biglock); ++subscribers; - biglock = false; return true; } void CoreVideoSource::unsubscribe() { - // Fast lock - { - bool expected = false; - while (!biglock.compare_exchange_weak(expected, true)) - expected = false; - } + biglock.lock(); if (--subscribers == 0) { if (deleteOnClose) { - biglock = false; + biglock.unlock(); + // DANGEROUS: No member access after this point, that's why we manually unlock delete this; return; } } - biglock = false; + biglock.unlock(); } void CoreVideoSource::setDeleteOnClose(bool newstate) { - // Fast lock - { - bool expected = false; - while (!biglock.compare_exchange_weak(expected, true)) - expected = false; - } + QMutexLocker locker(&biglock); deleteOnClose = newstate; - biglock = false; } void CoreVideoSource::stopSource() { + QMutexLocker locker(&biglock); stopped = true; emit sourceStopped(); } void CoreVideoSource::restartSource() { + QMutexLocker locker(&biglock); stopped = false; } diff --git a/src/video/corevideosource.h b/src/video/corevideosource.h index 888cc063a..b09b2ecc6 100644 --- a/src/video/corevideosource.h +++ b/src/video/corevideosource.h @@ -24,6 +24,7 @@ #include #include #include "videosource.h" +#include /// A VideoSource that emits frames received by Core class CoreVideoSource : public VideoSource @@ -52,7 +53,7 @@ private: private: std::atomic_int subscribers; ///< Number of suscribers std::atomic_bool deleteOnClose; ///< If true, self-delete after the last suscriber is gone - std::atomic_bool biglock; ///< Fast lock + QMutex biglock; std::atomic_bool stopped; friend class CoreAV;