67 lines
2.1 KiB
C++
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));
|
||
|
}
|
||
|
}
|
||
|
}
|