#include "SingletonProcess.h" #include "BoostLog.h" #ifdef WIN32 #include "Windows.h" #else #include #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::create_only, name.data(), 64, 1024); m_thread = std::make_unique(&SingletonProcess::run, this); } else { m_messageQueue = std::make_unique(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)); } } }