From 6d25342302aad89b4b107e3304cf14c624c44ea5 Mon Sep 17 00:00:00 2001 From: Michael Fabian 'Xaymar' Dirks Date: Thu, 8 Nov 2018 04:25:21 +0100 Subject: [PATCH] obs-source: Check for early source destruction This should prevent problems where the source is destroyed but a pointer is still around to it. --- source/obs-source.cpp | 44 ++++++++++++++++++++++++++++++++++++++++--- source/obs-source.hpp | 4 ++++ 2 files changed, 45 insertions(+), 3 deletions(-) diff --git a/source/obs-source.cpp b/source/obs-source.cpp index 370a52d2..a23c5638 100644 --- a/source/obs-source.cpp +++ b/source/obs-source.cpp @@ -19,9 +19,21 @@ #include "obs-source.hpp" +void obs::source::handle_destroy(void* p, calldata_t* calldata){ + obs::source* self = reinterpret_cast(p); + obs_source_t* source; + if (calldata_get_ptr(calldata, "source", &source)) { + if (self->self == source) { + self->self = nullptr; + } + } +} + obs::source::~source() { - if (this->track_ownership) { + auto sh = obs_source_get_signal_handler(this->self); + signal_handler_disconnect(sh, "destroy", obs::source::handle_destroy, this); + if (this->track_ownership && this->self) { obs_source_release(this->self); } this->self = nullptr; @@ -34,6 +46,8 @@ obs::source::source(std::string name, bool track_ownership, bool add_reference) if (!add_reference) { obs_source_release(this->self); } + auto sh = obs_source_get_signal_handler(this->self); + signal_handler_connect(sh, "destroy", obs::source::handle_destroy, this); } obs::source::source(obs_source_t* source, bool track_ownership, bool add_reference) @@ -43,16 +57,23 @@ obs::source::source(obs_source_t* source, bool track_ownership, bool add_referen if (add_reference) { obs_source_addref(this->self); } + auto sh = obs_source_get_signal_handler(this->self); + signal_handler_connect(sh, "destroy", obs::source::handle_destroy, this); } obs::source& obs::source::operator=(const source& ref) { if (this != &ref) { if (self) { - obs_source_release(self); + if (track_ownership) { + obs_source_release(self); + } } self = ref.self; - obs_source_addref(self); + track_ownership = ref.track_ownership; + if (track_ownership) { + obs_source_addref(self); + } } return *this; } @@ -68,24 +89,41 @@ obs::source& obs::source::operator=(source&& ref) noexcept obs_source_type obs::source::type() { + if (!self) { + return (obs_source_type)-1; + } return obs_source_get_type(self); } void* obs::source::type_data() { + if (!self) { + return nullptr; + } return obs_source_get_type_data(self); } uint32_t obs::source::width() { + if (!self) { + return 0; + } return obs_source_get_width(self); } uint32_t obs::source::height() { + if (!self) { + return 0; + } return obs_source_get_height(self); } +bool obs::source::destroyed() +{ + return self == nullptr; +} + void obs::source::clear() { self = nullptr; diff --git a/source/obs-source.hpp b/source/obs-source.hpp index 45c2451d..45cc1faa 100644 --- a/source/obs-source.hpp +++ b/source/obs-source.hpp @@ -33,6 +33,8 @@ namespace obs { obs_source_t* self; bool track_ownership = false; + static void handle_destroy(void* p, calldata_t* calldata); + public: virtual ~source(); @@ -51,6 +53,8 @@ namespace obs { uint32_t width(); uint32_t height(); + bool destroyed(); + public: // Unsafe Methods void clear();