diff options
author | Jeff Hatch <jhatch@multitech.com> | 2020-04-17 07:54:30 -0500 |
---|---|---|
committer | Jeff Hatch <jhatch@multitech.com> | 2020-04-17 07:54:30 -0500 |
commit | f3c24e90ea78d45e995e048a2c60ab828995fd3f (patch) | |
tree | e06153349d380256059021e177107eee407ee002 | |
parent | 8ad5075256df8b359e2a291fbe0b15f89d35d073 (diff) | |
parent | 791492306113c2f22af4a15fc4527c6b27cbfc96 (diff) | |
download | libmts-io-f3c24e90ea78d45e995e048a2c60ab828995fd3f.tar.gz libmts-io-f3c24e90ea78d45e995e048a2c60ab828995fd3f.tar.bz2 libmts-io-f3c24e90ea78d45e995e048a2c60ab828995fd3f.zip |
Merge branch 'MTX-3262-single-instance-guard-revert' into 'master'
Revert "MTX-3262 mpower: lockfile rewrite for interprocess communication safety"
See merge request !17
-rw-r--r-- | include/mts/MTS_IO_LockFile.h | 6 | ||||
-rw-r--r-- | src/MTS_IO_LockFile.cpp | 94 |
2 files changed, 70 insertions, 30 deletions
diff --git a/include/mts/MTS_IO_LockFile.h b/include/mts/MTS_IO_LockFile.h index 22e641b..730cf3c 100644 --- a/include/mts/MTS_IO_LockFile.h +++ b/include/mts/MTS_IO_LockFile.h @@ -34,8 +34,11 @@ namespace MTS { namespace IO { + class LockFile : MTS::NonCopyable { + public: + LockFile(const std::string& sFilePath); virtual ~LockFile(); @@ -43,10 +46,11 @@ namespace MTS { void unlock(); bool isLocked(); + protected: + private: std::string m_sFile; int m_iLockFd; - int m_iLockErr; }; } diff --git a/src/MTS_IO_LockFile.cpp b/src/MTS_IO_LockFile.cpp index 7f84f42..b74ba73 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,7 +29,13 @@ #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; @@ -37,49 +43,79 @@ 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; } - m_iLockFd = ::open(m_sFile.c_str(), O_CREAT | O_RDWR, 0644); - if (m_iLockFd >= 0) { - MTS::Timer timer; - timer.start(); - while (timer.getMillis() < attemptMillis) { - m_iLockErr = ::flock(m_iLockFd, LOCK_EX | LOCK_NB); - if (m_iLockErr == 0) { + 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; - } else if (errno != EWOULDBLOCK) { - break; } - ::usleep(((rand() % 10) + 1) * 100000); //Sleep from 100ms to 1 Second } - ::close(m_iLockFd); + uint32_t randomSleepTime = ((rand() % 10) + 1) * 100000; //Sleep from 100ms to 1 Second + ::usleep(randomSleepTime); } - m_iLockFd = -1; return false; } -void LockFile::unlock() -{ - ::flock(m_iLockFd, LOCK_UN); - ::close(m_iLockFd); - m_iLockFd = -1; - m_iLockErr = -1; +void LockFile::unlock() { + if(isLocked()) { + ::unlink(m_sFile.c_str()); + //TODO: flock cleanup : flock(m_iLockFd, LOCK_UN); + m_iLockFd = -1; + } } -bool LockFile::isLocked() -{ - return m_iLockErr == 0; +bool LockFile::isLocked() { + return m_iLockFd >= 0; } + |