mirror of
https://github.com/Xaymar/obs-StreamFX
synced 2024-11-13 07:15:06 +00:00
obs/source-tracker: Don't leak pointers to sources
This commit is contained in:
parent
f5bc53564d
commit
f98319dee7
2 changed files with 44 additions and 37 deletions
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
#include "obs-source-tracker.hpp"
|
#include "obs-source-tracker.hpp"
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
|
#include "obs/obs-tools.hpp"
|
||||||
#include "plugin.hpp"
|
#include "plugin.hpp"
|
||||||
|
|
||||||
static std::shared_ptr<obs::source_tracker> source_tracker_instance;
|
static std::shared_ptr<obs::source_tracker> source_tracker_instance;
|
||||||
|
@ -35,17 +36,19 @@ try {
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* name = obs_source_get_name(target);
|
const char* name = obs_source_get_name(target);
|
||||||
if (!name) {
|
if (!name) { // Do not track unnamed sources.
|
||||||
// Do not track unnamed sources.
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
obs_weak_source_t* weak = obs_source_get_weak_source(target);
|
obs_weak_source_t* weak = obs_source_get_weak_source(target);
|
||||||
if (!weak) {
|
if (!weak) { // This source has already been deleted, do not track.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
self->_source_map.insert({std::string(name), weak});
|
{
|
||||||
|
std::unique_lock<std::mutex> ul(self->_lock);
|
||||||
|
self->_sources.insert({std::string(name), {weak, obs::obs_weak_source_deleter}});
|
||||||
|
}
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
LOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
|
LOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
|
||||||
}
|
}
|
||||||
|
@ -62,18 +65,18 @@ try {
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* name = obs_source_get_name(target);
|
const char* name = obs_source_get_name(target);
|
||||||
if (!name) {
|
if (!name) { // Not tracking unnamed sources.
|
||||||
// Not tracking unnamed sources.
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto found = self->_source_map.find(std::string(name));
|
{
|
||||||
if (found == self->_source_map.end()) {
|
std::unique_lock<std::mutex> ul(self->_lock);
|
||||||
return;
|
auto found = self->_sources.find(std::string(name));
|
||||||
|
if (found == self->_sources.end()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
self->_sources.erase(found);
|
||||||
}
|
}
|
||||||
|
|
||||||
obs_weak_source_release(found->second);
|
|
||||||
self->_source_map.erase(found);
|
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
LOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
|
LOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
|
||||||
}
|
}
|
||||||
|
@ -94,20 +97,23 @@ try {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto found = self->_source_map.find(std::string(prev_name));
|
{
|
||||||
if (found == self->_source_map.end()) {
|
std::unique_lock<std::mutex> ul(self->_lock);
|
||||||
// Untracked source, insert.
|
auto found = self->_sources.find(std::string(prev_name));
|
||||||
obs_weak_source_t* weak = obs_source_get_weak_source(target);
|
if (found == self->_sources.end()) {
|
||||||
if (!weak) {
|
// Untracked source, insert.
|
||||||
|
obs_weak_source_t* weak = obs_source_get_weak_source(target);
|
||||||
|
if (!weak) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
self->_sources.insert({new_name, {weak, obs::obs_weak_source_deleter}});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
self->_source_map.insert({new_name, weak});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Insert at new key, remove old pair.
|
// Insert at new key, remove old pair.
|
||||||
self->_source_map.insert({new_name, found->second});
|
self->_sources.insert({new_name, found->second});
|
||||||
self->_source_map.erase(found);
|
self->_sources.erase(found);
|
||||||
|
}
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
LOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
|
LOG_ERROR("Unexpected exception in function '%s'.", __FUNCTION_NAME__);
|
||||||
}
|
}
|
||||||
|
@ -144,37 +150,36 @@ obs::source_tracker::~source_tracker()
|
||||||
signal_handler_disconnect(osi, "source_rename", &source_rename_handler, this);
|
signal_handler_disconnect(osi, "source_rename", &source_rename_handler, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto kv : this->_source_map) {
|
this->_sources.clear();
|
||||||
obs_weak_source_release(kv.second);
|
|
||||||
}
|
|
||||||
this->_source_map.clear();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void obs::source_tracker::enumerate(enumerate_cb_t ecb, filter_cb_t fcb)
|
void obs::source_tracker::enumerate(enumerate_cb_t ecb, filter_cb_t fcb)
|
||||||
{
|
{
|
||||||
// Need func-local copy, otherwise we risk corruption if a new source is created or destroyed.
|
// Need func-local copy, otherwise we risk corruption if a new source is created or destroyed.
|
||||||
auto source_map_copy = this->_source_map;
|
decltype(_sources) _clone;
|
||||||
for (auto kv : this->_source_map) {
|
{
|
||||||
obs_source_t* source = obs_weak_source_get_source(kv.second);
|
std::unique_lock<std::mutex> ul(_lock);
|
||||||
|
_clone = _sources;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto kv : _clone) {
|
||||||
|
auto source =
|
||||||
|
std::shared_ptr<obs_source_t>(obs_weak_source_get_source(kv.second.get()), obs::obs_source_deleter);
|
||||||
if (!source) {
|
if (!source) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fcb) {
|
if (fcb) {
|
||||||
if (fcb(kv.first, source)) {
|
if (fcb(kv.first, source.get())) {
|
||||||
obs_source_release(source);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ecb) {
|
if (ecb) {
|
||||||
if (ecb(kv.first, source)) {
|
if (ecb(kv.first, source.get())) {
|
||||||
obs_source_release(source);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
obs_source_release(source);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,10 +21,12 @@
|
||||||
#include "common.hpp"
|
#include "common.hpp"
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
namespace obs {
|
namespace obs {
|
||||||
class source_tracker {
|
class source_tracker {
|
||||||
std::map<std::string, obs_weak_source_t*> _source_map;
|
std::map<std::string, std::shared_ptr<obs_weak_source_t>> _sources;
|
||||||
|
std::mutex _lock;
|
||||||
|
|
||||||
static void source_create_handler(void* ptr, calldata_t* data) noexcept;
|
static void source_create_handler(void* ptr, calldata_t* data) noexcept;
|
||||||
static void source_destroy_handler(void* ptr, calldata_t* data) noexcept;
|
static void source_destroy_handler(void* ptr, calldata_t* data) noexcept;
|
||||||
|
|
Loading…
Reference in a new issue