summaryrefslogtreecommitdiff
path: root/src/MTS_IO_LockFile.cpp
diff options
context:
space:
mode:
authorJesse Gilles <jgilles@multitech.com>2015-04-20 17:14:31 -0500
committerJesse Gilles <jgilles@multitech.com>2015-04-20 17:14:31 -0500
commitd84d880627bcc1e1898a8f96b861bc25863ec86c (patch)
treee7db4eef6a8e8254eaa6ba0c7e5d56098af19d16 /src/MTS_IO_LockFile.cpp
downloadlibmts-io-d84d880627bcc1e1898a8f96b861bc25863ec86c.tar.gz
libmts-io-d84d880627bcc1e1898a8f96b861bc25863ec86c.tar.bz2
libmts-io-d84d880627bcc1e1898a8f96b861bc25863ec86c.zip
initial commit
Diffstat (limited to 'src/MTS_IO_LockFile.cpp')
-rw-r--r--src/MTS_IO_LockFile.cpp109
1 files changed, 109 insertions, 0 deletions
diff --git a/src/MTS_IO_LockFile.cpp b/src/MTS_IO_LockFile.cpp
new file mode 100644
index 0000000..c013699
--- /dev/null
+++ b/src/MTS_IO_LockFile.cpp
@@ -0,0 +1,109 @@
+/*
+ * Copyright (C) 2015 by Multi-Tech Systems
+ *
+ * This file is part of libmts_io.
+ *
+ * libmts_io is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * libmts_io is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with libmts_io. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+/*!
+ \file MTS_IO_LockFile.cpp
+ \brief A brief description
+ \date Oct 8, 2014
+ \author sgodinez
+
+ A more elaborate description
+*/
+
+#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;
+
+LockFile::LockFile(const std::string& sFile)
+: m_sFile(sFile)
+, m_iLockFd(-1)
+{
+
+}
+
+LockFile::~LockFile() {
+ unlock();
+}
+
+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};
+ sprintf(buf, "%4d\n", getpid());
+ write(m_iLockFd, buf, strlen(buf));
+ close(m_iLockFd);
+ return true;
+ }
+ uint32_t randomSleepTime = ((rand() % 10) + 1) * 100000; //Sleep from 100ms to 1 Second
+ ::usleep(randomSleepTime);
+ }
+ return false;
+}
+
+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_iLockFd >= 0;
+}
+