summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeff Hatch <jhatch@multitech.com>2020-04-17 07:54:30 -0500
committerJeff Hatch <jhatch@multitech.com>2020-04-17 07:54:30 -0500
commitf3c24e90ea78d45e995e048a2c60ab828995fd3f (patch)
treee06153349d380256059021e177107eee407ee002
parent8ad5075256df8b359e2a291fbe0b15f89d35d073 (diff)
parent791492306113c2f22af4a15fc4527c6b27cbfc96 (diff)
downloadlibmts-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.h6
-rw-r--r--src/MTS_IO_LockFile.cpp94
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;
}
+