GstEnginePipeline: Fix file descriptor exhaustion by using shared thread pool
Replace per-pipeline QThreadPool with a shared static pool to prevent file descriptor and thread exhaustion. Each GstEnginePipeline was creating its own thread pool, leading to resource accumulation during frequent pipeline creation/destruction (track changes, seeking, crossfade). The shared pool is limited to 2 threads max since state changes are typically sequential per pipeline. This prevents the crash in g_wakeup_new() when creating eventfd for new thread event dispatchers. Fixes #1687
This commit is contained in:
@@ -42,6 +42,7 @@
|
||||
#include <QObject>
|
||||
#include <QCoreApplication>
|
||||
#include <QtConcurrentRun>
|
||||
#include <QThreadPool>
|
||||
#include <QFuture>
|
||||
#include <QFutureWatcher>
|
||||
#include <QMutex>
|
||||
@@ -98,6 +99,23 @@ constexpr int kEqBandFrequencies[] = { 60, 170, 310, 600, 1000, 3000, 6000, 1200
|
||||
|
||||
int GstEnginePipeline::sId = 1;
|
||||
|
||||
QThreadPool *GstEnginePipeline::shared_state_threadpool() {
|
||||
|
||||
// C++11 guarantees thread-safe initialization of static local variables
|
||||
static QThreadPool pool;
|
||||
static const auto init = []() {
|
||||
// Limit the number of threads to prevent resource exhaustion
|
||||
// Use 2 threads max since state changes are typically sequential per pipeline
|
||||
pool.setMaxThreadCount(2);
|
||||
return true;
|
||||
}();
|
||||
|
||||
Q_UNUSED(init);
|
||||
|
||||
return &pool;
|
||||
|
||||
}
|
||||
|
||||
GstEnginePipeline::GstEnginePipeline(QObject *parent)
|
||||
: QObject(parent),
|
||||
id_(sId++),
|
||||
@@ -1848,7 +1866,7 @@ QFuture<GstStateChangeReturn> GstEnginePipeline::SetState(const GstState state)
|
||||
watcher->deleteLater();
|
||||
SetStateFinishedSlot(state, state_change_return);
|
||||
});
|
||||
QFuture<GstStateChangeReturn> future = QtConcurrent::run(&set_state_threadpool_, &gst_element_set_state, pipeline_, state);
|
||||
QFuture<GstStateChangeReturn> future = QtConcurrent::run(shared_state_threadpool(), &gst_element_set_state, pipeline_, state);
|
||||
watcher->setFuture(future);
|
||||
|
||||
return future;
|
||||
|
||||
Reference in New Issue
Block a user