summaryrefslogtreecommitdiff
path: root/src/MTS_IO_LockFile.cpp
diff options
context:
space:
mode:
authorMaksym Telychko <maksym.telychko@globallogic.com>2020-03-24 17:41:04 +0200
committerAndrii Pientsov <andrii.pientsov@globallogic.com>2020-05-26 19:48:31 +0300
commit620bd2637b40d718dd5886ce7df0a19b73ea8875 (patch)
treea1937c07a912e8c0b079b4ba3b6aa1dd82aec675 /src/MTS_IO_LockFile.cpp
parentb3a9a71afdb0d6f4f104543cedba89d011ca68df (diff)
downloadlibmts-io-620bd2637b40d718dd5886ce7df0a19b73ea8875.tar.gz
libmts-io-620bd2637b40d718dd5886ce7df0a19b73ea8875.tar.bz2
libmts-io-620bd2637b40d718dd5886ce7df0a19b73ea8875.zip
MTX-3262 mpower: lockfile rewrite for interprocess communication safety
Previous implementation was not thread/interprocess safe due to pid management Fixes: Single instance guard.
Diffstat (limited to 'src/MTS_IO_LockFile.cpp')
-rw-r--r--src/MTS_IO_LockFile.cpp92
1 files changed, 25 insertions, 67 deletions
diff --git a/src/MTS_IO_LockFile.cpp b/src/MTS_IO_LockFile.cpp
index b74ba73..4312ce4 100644
--- a/src/MTS_IO_LockFile.cpp
+++ b/src/MTS_IO_LockFile.cpp
@@ -18,9 +18,9 @@
*
*/
-/*!
+/*!
\file MTS_IO_LockFile.cpp
- \brief A brief description
+ \brief A brief description
\date Oct 8, 2014
\author sgodinez
@@ -29,13 +29,7 @@
#include <mts/MTS_IO_LockFile.h>
#include <mts/MTS_Timer.h>
-#include <mts/MTS_Logger.h>
-#include <mts/MTS_System.h>
-#include <mts/MTS_Text.h>
#include <sys/file.h>
-#include <sys/stat.h>
-#include <errno.h>
-#include <string.h>
#include <unistd.h>
using namespace MTS::IO;
@@ -43,79 +37,43 @@ using namespace MTS::IO;
LockFile::LockFile(const std::string& sFile)
: m_sFile(sFile)
, m_iLockFd(-1)
+, m_iLockErr(-1)
{
-
}
-LockFile::~LockFile() {
+LockFile::~LockFile()
+{
unlock();
}
-bool LockFile::lock(uint32_t attemptMillis) {
- if(isLocked()) {
+bool LockFile::lock(uint32_t attemptMillis)
+{
+ if (isLocked())
return true;
- }
MTS::Timer timer;
-
timer.start();
- while(timer.getMillis() < attemptMillis) {
- m_iLockFd =::open(m_sFile.c_str(), O_CREAT | O_WRONLY | O_TRUNC | O_EXCL, 0644);
- if (m_iLockFd < 0) {
- // device already locked -> bail out
- printWarning("LockFile| Failed to Lock [%s] [%d][%s]", m_sFile.c_str(), errno, strerror(errno));
-
- //Check if lock file's process still exists
- std::string sResult;
- if(MTS::System::readFile(m_sFile, sResult) == 0 && sResult.size() > 0) {
- struct stat sts;
- std::string sProc = "/proc/" + MTS::Text::trim(sResult);
- if (stat(sProc.c_str(), &sts) == -1 && errno == ENOENT) {
- printWarning("LockFile| Current Lock's Process [%s] does not exist. Removing lock.", sResult.c_str());
- // process doesn't exist -> remove file
- ::unlink(m_sFile.c_str());
- }
- }
-
- } else {
- //TODO: Investigate using flock in addition to minicom-style lock : flock(m_iLockFd, LOCK_EX | LOCK_NB);
-
- // %4d to make concurrent mgetty (if any) happy.
- // Mgetty treats 4-bytes lock files as binary,
- // not text, PID. Making 5+ char file. Brrr...
- char buf[256] = {0};
- size_t written = 0;
-
- sprintf(buf, "%4d\n", getpid());
- size_t wsize = strlen(buf);
-
- written = write(m_iLockFd, buf, wsize);
-
- if (wsize != written) {
- printError("LockFile| Error writing to lock file [%s] [%d][%s]", m_sFile.c_str(), errno, strerror(errno));
- close(m_iLockFd);
- return false;
- }
- else {
- close(m_iLockFd);
- return true;
- }
- }
- uint32_t randomSleepTime = ((rand() % 10) + 1) * 100000; //Sleep from 100ms to 1 Second
- ::usleep(randomSleepTime);
+ m_iLockFd = ::open(m_sFile.c_str(), O_CREAT | O_RDWR, 0666);
+ while (timer.getMillis() < attemptMillis) {
+ m_iLockErr = ::flock(m_iLockFd, LOCK_EX | LOCK_NB);
+ if (m_iLockErr == 0)
+ return true;
+ ::usleep(((rand() % 10) + 1) * 100000); //Sleep from 100ms to 1 Second
}
+ ::close(m_iLockFd);
+ m_iLockFd = -1;
return false;
}
-void LockFile::unlock() {
- if(isLocked()) {
- ::unlink(m_sFile.c_str());
- //TODO: flock cleanup : flock(m_iLockFd, LOCK_UN);
- m_iLockFd = -1;
- }
+void LockFile::unlock()
+{
+ ::flock(m_iLockFd, LOCK_UN);
+ ::close(m_iLockFd);
+ m_iLockFd = -1;
+ m_iLockErr = -1;
}
-bool LockFile::isLocked() {
- return m_iLockFd >= 0;
+bool LockFile::isLocked()
+{
+ return m_iLockErr == 0;
}
-