UI: Detect other instances of obs on FreeBSD
Detect other instances of the obs by creating an extra dummy thread, named "OBS runonce". The process of threads enumeration of current user is guarded by an O_EXLOCK file advisory lock when opening the lock file. Such file lock would be dropped once the thread name is changed. This should be usable on FreeBSD and possibly compile on DragonFly BSD. fixes: #3053
This commit is contained in:
parent
013dd5a7a3
commit
f8aa02897f
@ -132,6 +132,11 @@ elseif(UNIX)
|
||||
|
||||
set(obs_PLATFORM_LIBRARIES
|
||||
Qt5::X11Extras)
|
||||
|
||||
if("${CMAKE_SYSTEM_NAME}" MATCHES "FreeBSD")
|
||||
list(APPEND obs_PLATFORM_LIBRARIES
|
||||
procstat)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
if(BROWSER_AVAILABLE_INTERNAL)
|
||||
|
@ -1950,6 +1950,8 @@ static int run_program(fstream &logFile, int argc, char *argv[])
|
||||
CheckAppWithSameBundleID(already_running);
|
||||
#elif defined(__linux__)
|
||||
RunningInstanceCheck(already_running);
|
||||
#elif defined(__FreeBSD__) || defined(__DragonFly__)
|
||||
PIDFileCheck(already_running);
|
||||
#endif
|
||||
|
||||
if (!already_running) {
|
||||
|
@ -35,6 +35,17 @@
|
||||
#include <stdio.h>
|
||||
#include <sys/un.h>
|
||||
#endif
|
||||
#if defined(__FreeBSD__) || defined(__DragonFly__)
|
||||
#include <sys/param.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/user.h>
|
||||
#include <libprocstat.h>
|
||||
|
||||
#include <condition_variable>
|
||||
#include <mutex>
|
||||
#include <thread>
|
||||
#endif
|
||||
|
||||
using namespace std;
|
||||
|
||||
@ -90,6 +101,75 @@ void RunningInstanceCheck(bool &already_running)
|
||||
fclose(fp);
|
||||
}
|
||||
#endif
|
||||
#if defined(__FreeBSD__) || defined(__DragonFly__)
|
||||
struct RunOnce {
|
||||
std::thread thr;
|
||||
static const char *thr_name;
|
||||
std::condition_variable cv;
|
||||
std::condition_variable wait_cv;
|
||||
std::mutex mtx;
|
||||
bool exiting = false;
|
||||
bool name_changed = false;
|
||||
|
||||
void thr_proc()
|
||||
{
|
||||
std::unique_lock<std::mutex> lk(mtx);
|
||||
pthread_setname_np(pthread_self(), thr_name);
|
||||
name_changed = true;
|
||||
wait_cv.notify_all();
|
||||
cv.wait(lk, [this]() { return exiting; });
|
||||
}
|
||||
|
||||
~RunOnce()
|
||||
{
|
||||
if (thr.joinable()) {
|
||||
std::unique_lock<std::mutex> lk(mtx);
|
||||
exiting = true;
|
||||
cv.notify_one();
|
||||
lk.unlock();
|
||||
thr.join();
|
||||
}
|
||||
}
|
||||
} RO;
|
||||
const char *RunOnce::thr_name = "OBS runonce";
|
||||
|
||||
void PIDFileCheck(bool &already_running)
|
||||
{
|
||||
std::string tmpfile_name =
|
||||
"/tmp/obs-studio.lock." + to_string(geteuid());
|
||||
int fd = open(tmpfile_name.c_str(), O_RDWR | O_CREAT | O_EXLOCK, 0600);
|
||||
if (fd == -1) {
|
||||
already_running = true;
|
||||
return;
|
||||
}
|
||||
|
||||
already_running = false;
|
||||
|
||||
procstat *ps = procstat_open_sysctl();
|
||||
unsigned int count;
|
||||
auto procs = procstat_getprocs(ps, KERN_PROC_UID | KERN_PROC_INC_THREAD,
|
||||
geteuid(), &count);
|
||||
for (unsigned int i = 0; i < count; i++) {
|
||||
if (!strncmp(procs[i].ki_tdname, RunOnce::thr_name,
|
||||
sizeof(procs[i].ki_tdname))) {
|
||||
already_running = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
procstat_freeprocs(ps, procs);
|
||||
procstat_close(ps);
|
||||
|
||||
RO.thr = std::thread(std::mem_fn(&RunOnce::thr_proc), &RO);
|
||||
|
||||
{
|
||||
std::unique_lock<std::mutex> lk(RO.mtx);
|
||||
RO.wait_cv.wait(lk, []() { return RO.name_changed; });
|
||||
}
|
||||
|
||||
unlink(tmpfile_name.c_str());
|
||||
close(fd);
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline bool check_path(const char *data, const char *path,
|
||||
string &output)
|
||||
|
@ -73,3 +73,6 @@ void CheckAppWithSameBundleID(bool &already_running);
|
||||
#ifdef __linux__
|
||||
void RunningInstanceCheck(bool &already_running);
|
||||
#endif
|
||||
#if defined(__FreeBSD__) || defined(__DragonFly__)
|
||||
void PIDFileCheck(bool &already_running);
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user