Kylin/Universal/SingletonProcess.cpp
2023-07-25 10:40:14 +08:00

67 lines
2.1 KiB
C++

#include "SingletonProcess.h"
#include "BoostLog.h"
#ifdef WIN32
#include "Windows.h"
#else
#include <sys/file.h>
#endif
SingletonProcess::SingletonProcess(const std::string_view &name) {
#ifdef WIN32
m_handle = CreateMutex(NULL, FALSE, name.data());
if (m_handle) {
if (ERROR_ALREADY_EXISTS == GetLastError()) {
m_alreadyRun = true;
}
}
#else
std::ostringstream oss;
oss << "/tmp/" << name;
int pidFile = open(oss.str().data(), O_CREAT | O_RDWR, 0666);
m_handle = flock(pidFile, LOCK_EX | LOCK_NB);
if (m_handle) {
if (EWOULDBLOCK == errno) m_alreadyRun = true;
}
#endif
if (!m_alreadyRun) {
boost::interprocess::message_queue::remove(name.data());
m_messageQueue = std::make_unique<boost::interprocess::message_queue>(boost::interprocess::create_only,
name.data(), 64, 1024);
m_thread = std::make_unique<std::thread>(&SingletonProcess::run, this);
} else {
m_messageQueue =
std::make_unique<boost::interprocess::message_queue>(boost::interprocess::open_only, name.data());
}
}
bool SingletonProcess::alreadyRun() const {
return m_alreadyRun;
}
SingletonProcess::~SingletonProcess() {
m_exit = true;
m_conditionVariable.notify_all();
if (m_thread && m_thread->joinable()) m_thread->join();
}
bool SingletonProcess::sendMessage(const char *data, size_t size) {
if (!m_alreadyRun) return false;
return m_messageQueue->try_send(data, size, 0);
}
void SingletonProcess::run() {
char buffer[1024];
while (!m_exit) {
unsigned int priority;
boost::interprocess::message_queue::size_type receivedSize;
bool status = m_messageQueue->try_receive(buffer, sizeof(buffer), receivedSize, priority);
if (status) {
messageHandler(buffer, receivedSize);
} else {
std::unique_lock locker(m_mutex);
m_conditionVariable.wait_for(locker, std::chrono::milliseconds(500));
}
}
}