summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeff Hatch <jhatch@multitech.com>2020-04-13 14:43:35 -0500
committerJeff Hatch <jhatch@multitech.com>2020-04-13 14:43:35 -0500
commit8ad5075256df8b359e2a291fbe0b15f89d35d073 (patch)
tree6cf2facfea539fa8cdf622061184ddccb7d24390
parent36201df0d08daeeb64bb3923da789025a277a4ef (diff)
parent24f7d2e0935a3bb43a6b96c0cdc58b1ed3c1cddf (diff)
downloadlibmts-io-8ad5075256df8b359e2a291fbe0b15f89d35d073.tar.gz
libmts-io-8ad5075256df8b359e2a291fbe0b15f89d35d073.tar.bz2
libmts-io-8ad5075256df8b359e2a291fbe0b15f89d35d073.zip
Merge branch 'MTX-3262-single-instance-guard' into 'master'
MTX-3262 mpower: lockfile rewrite for interprocess communication safety See merge request !16
-rw-r--r--include/mts/MTS_IO_LockFile.h6
-rw-r--r--src/MTS_IO_LockFile.cpp94
2 files changed, 30 insertions, 70 deletions
diff --git a/include/mts/MTS_IO_LockFile.h b/include/mts/MTS_IO_LockFile.h
index 730cf3c..22e641b 100644
--- a/include/mts/MTS_IO_LockFile.h
+++ b/include/mts/MTS_IO_LockFile.h
@@ -34,11 +34,8 @@
namespace MTS {
namespace IO {
-
class LockFile : MTS::NonCopyable {
-
public:
-
LockFile(const std::string& sFilePath);
virtual ~LockFile();
@@ -46,11 +43,10 @@ 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 b74ba73..7f84f42 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,49 @@ 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);
+ 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) {
return true;
+ } else if (errno != EWOULDBLOCK) {
+ break;
}
+ ::usleep(((rand() % 10) + 1) * 100000); //Sleep from 100ms to 1 Second
}
- uint32_t randomSleepTime = ((rand() % 10) + 1) * 100000; //Sleep from 100ms to 1 Second
- ::usleep(randomSleepTime);
+ ::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;
}
-