Added FileLocker class 38/29738/6
authorSebastian Grabowski <s.grabowski@samsung.com>
Mon, 27 Oct 2014 11:16:24 +0000 (12:16 +0100)
committerSebastian Grabowski <s.grabowski@samsung.com>
Wed, 19 Nov 2014 13:18:57 +0000 (14:18 +0100)
Initial version of file locking class for use in upcoming offline mode.

Change-Id: I4acd73ba56d09393bd138da94559b2be18e2cc3b
Signed-off-by: Sebastian Grabowski <s.grabowski@samsung.com>
src/common/CMakeLists.txt
src/common/file-lock.cpp [new file with mode: 0644]
src/common/include/file-lock.h [new file with mode: 0644]

index 9a9d57c..68120d1 100644 (file)
@@ -10,6 +10,8 @@ PKG_CHECK_MODULES(COMMON_DEP
     cynara-client
     )
 
+FIND_PACKAGE(Boost REQUIRED)
+
 INCLUDE_DIRECTORIES(SYSTEM
     ${COMMON_DEP_INCLUDE_DIRS}
     )
@@ -20,6 +22,7 @@ INCLUDE_DIRECTORIES(
     ${DPL_PATH}/core/include
     ${DPL_PATH}/log/include
     ${DPL_PATH}/db/include
+    ${Boost_INCLUDE_DIRS}
     )
 
 SET(COMMON_SOURCES
@@ -39,6 +42,7 @@ SET(COMMON_SOURCES
     ${DPL_PATH}/db/src/naive_synchronization_object.cpp
     ${DPL_PATH}/db/src/sql_connection.cpp
     ${COMMON_PATH}/cynara.cpp
+    ${COMMON_PATH}/file-lock.cpp
     ${COMMON_PATH}/protocols.cpp
     ${COMMON_PATH}/message-buffer.cpp
     ${COMMON_PATH}/privilege_db.cpp
diff --git a/src/common/file-lock.cpp b/src/common/file-lock.cpp
new file mode 100644 (file)
index 0000000..1b9b0b8
--- /dev/null
@@ -0,0 +1,106 @@
+/*
+ *  Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Contact: Rafal Krypa <r.krypa@samsung.com>
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License
+ */
+/*
+ * @file        file-lock.cpp
+ * @author      Sebastian Grabowski (s.grabowski@samsung.com)
+ * @version     1.0
+ * @brief       Implementation of simple file locking for a service
+ */
+/* vim: set ts=4 et sw=4 tw=78 : */
+
+#include <fstream>
+#include <dpl/log/log.h>
+
+#include "file-lock.h"
+
+namespace SecurityManager {
+
+char const * const SERVICE_LOCK_FILE = tzplatform_mkpath3(TZ_SYS_RUN,
+                                                         "lock",
+                                                         "security-manager.lock");
+
+FileLocker::FileLocker(const std::string &lockFile, bool blocking)
+{
+    if (lockFile.empty()) {
+        LogError("File name can not be empty.");
+        ThrowMsg(FileLocker::Exception::LockFailed,
+                 "File name can not be empty.");
+    }
+    try {
+        m_locked = false;
+        m_blocking = blocking;
+        m_lockFile = lockFile;
+        Lock();
+    } catch (FileLocker::Exception::Base &e) {
+        LogError("Failed to lock " << lockFile << " file: "
+                 << e.DumpToString());
+        ThrowMsg(FileLocker::Exception::LockFailed,
+                 "Failed to lock " << lockFile << " file: "
+                 << e.DumpToString());
+    }
+}
+
+FileLocker::~FileLocker()
+{
+    Unlock();
+}
+
+bool FileLocker::Locked()
+{
+    return m_locked;
+}
+
+void FileLocker::Lock()
+{
+    if (m_locked)
+        return;
+    try {
+        if (!std::ifstream(m_lockFile).good())
+            std::ofstream(m_lockFile.c_str());
+        m_flock = boost::interprocess::file_lock(m_lockFile.c_str());
+        if (m_blocking) {
+            m_flock.lock();
+            m_locked = true;
+        } else
+            m_locked = m_flock.try_lock();
+    } catch (const std::exception &e) {
+            ThrowMsg(FileLocker::Exception::LockFailed,
+                     "Error while locking a file.");
+    }
+    if (m_locked) {
+        LogDebug("We have a lock on " << m_lockFile << " file.");
+    } else {
+        if (m_blocking) {
+            ThrowMsg(FileLocker::Exception::LockFailed,
+                     "Unable to lock file.");
+        } else {
+            LogDebug("Impossible to lock a file now.");
+        }
+    }
+}
+
+void FileLocker::Unlock()
+{
+    if (m_locked) {
+        m_flock.unlock();
+        LogDebug("Lock released.");
+    }
+}
+
+} // namespace SecurityManager
+
diff --git a/src/common/include/file-lock.h b/src/common/include/file-lock.h
new file mode 100644 (file)
index 0000000..620d757
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ *  Copyright (c) 2000 - 2014 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ *  Contact: Rafal Krypa <r.krypa@samsung.com>
+ *
+ *  Licensed under the Apache License, Version 2.0 (the "License");
+ *  you may not use this file except in compliance with the License.
+ *  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing, software
+ *  distributed under the License is distributed on an "AS IS" BASIS,
+ *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ *  See the License for the specific language governing permissions and
+ *  limitations under the License
+ */
+/*
+ * @file        file-lock.h
+ * @author      Sebastian Grabowski (s.grabowski@samsung.com)
+ * @version     1.0
+ * @brief       Implementation of simple file locking for a service
+ */
+/* vim: set ts=4 et sw=4 tw=78 : */
+
+#pragma once
+
+#include <boost/interprocess/sync/file_lock.hpp>
+
+#include <dpl/exception.h>
+#include <dpl/noncopyable.h>
+#include <tzplatform_config.h>
+
+namespace SecurityManager {
+
+extern char const * const SERVICE_LOCK_FILE;
+
+class FileLocker :
+    public Noncopyable
+{
+public:
+    class Exception
+    {
+    public:
+        DECLARE_EXCEPTION_TYPE(SecurityManager::Exception, Base)
+        DECLARE_EXCEPTION_TYPE(Base, LockFailed)
+    };
+
+    FileLocker(const std::string &lockFile, bool blocking = false);
+    ~FileLocker();
+
+    bool Locked();
+
+protected:
+    void Lock();
+    void Unlock();
+
+private:
+    std::string m_lockFile;
+    boost::interprocess::file_lock m_flock;
+    bool m_blocking;
+    bool m_locked;
+};
+
+} // namespace SecurityManager
+