Make thread-safe for db manager functions 21/75321/1
authorKyungwook Tak <k.tak@samsung.com>
Fri, 17 Jun 2016 10:31:53 +0000 (19:31 +0900)
committerKyungwook Tak <k.tak@samsung.com>
Fri, 17 Jun 2016 10:32:10 +0000 (19:32 +0900)
Change-Id: I175c7be11fb98502a57dc7c81bbfc9ee1bb8527d
Signed-off-by: Kyungwook Tak <k.tak@samsung.com>
src/framework/db/manager.cpp
src/framework/db/manager.h
src/framework/service/cs-logic.cpp
test/internals/test-db.cpp

index 5c64e01..ad80dfb 100644 (file)
@@ -193,34 +193,42 @@ void Manager::setSchemaVersion(int sv)
 //===========================================================================
 csr_state_e Manager::getEngineState(csr_engine_id_e id)
 {
-       std::lock_guard<std::mutex> l(this->m_mutex);
+       std::lock_guard<std::mutex> ll(this->m_mutex);
+
+       {
+               std::lock_guard<std::mutex> l(this->m_stateMutex);
 
-       if (this->m_stateMap.size() == 0) {
-               Statement stmt(this->m_conn, Query::SEL_ENGINE_STATE_ALL);
+               if (this->m_stateMap.size() == 0) {
+                       Statement stmt(this->m_conn, Query::SEL_ENGINE_STATE_ALL);
 
-               while (stmt.step()) {
-                       auto _id = static_cast<csr_engine_id_e>(stmt.getInt());
-                       auto _state = static_cast<csr_state_e>(stmt.getInt());
+                       while (stmt.step()) {
+                               auto _id = static_cast<csr_engine_id_e>(stmt.getInt());
+                               auto _state = static_cast<csr_state_e>(stmt.getInt());
 
-                       this->m_stateMap[_id] = _state;
+                               this->m_stateMap[_id] = _state;
+                       }
                }
-       }
 
-       return (this->m_stateMap.count(id) == 0) ? CSR_STATE_ENABLE : this->m_stateMap[id];
+               return (this->m_stateMap.count(id) == 0) ? CSR_STATE_ENABLE : this->m_stateMap[id];
+       }
 }
 
 void Manager::setEngineState(csr_engine_id_e id, csr_state_e state)
 {
-       std::lock_guard<std::mutex> l(this->m_mutex);
+       std::lock_guard<std::mutex> ll(this->m_mutex);
 
-       Statement stmt(this->m_conn, Query::INS_ENGINE_STATE);
+       {
+               std::lock_guard<std::mutex> l(this->m_stateMutex);
 
-       stmt.bind(static_cast<int>(id));
-       stmt.bind(static_cast<int>(state));
+               Statement stmt(this->m_conn, Query::INS_ENGINE_STATE);
 
-       stmt.exec();
+               stmt.bind(static_cast<int>(id));
+               stmt.bind(static_cast<int>(state));
 
-       this->m_stateMap[id] = state;
+               stmt.exec();
+
+               this->m_stateMap[id] = state;
+       }
 }
 
 //===========================================================================
@@ -230,6 +238,8 @@ void Manager::setEngineState(csr_engine_id_e id, csr_state_e state)
 time_t Manager::getLastScanTime(const std::string &dir,
                                                                const std::string &dataVersion)
 {
+       std::lock_guard<std::mutex> l(this->m_mutex);
+
        time_t latest = -1;
        std::string current = dir;
        Statement stmt(this->m_conn, Query::SEL_SCAN_REQUEST);
@@ -259,6 +269,8 @@ time_t Manager::getLastScanTime(const std::string &dir,
 void Manager::insertLastScanTime(const std::string &dir, time_t scanTime,
                                                                 const std::string &dataVersion)
 {
+       std::lock_guard<std::mutex> l(this->m_mutex);
+
        Statement stmt(this->m_conn, Query::INS_SCAN_REQUEST);
 
        stmt.bind(dir);
@@ -269,6 +281,8 @@ void Manager::insertLastScanTime(const std::string &dir, time_t scanTime,
 
 void Manager::deleteLastScanTime(const std::string &dir)
 {
+       std::lock_guard<std::mutex> l(this->m_mutex);
+
        Statement stmt(this->m_conn, Query::DEL_SCAN_REQUEST_BY_DIR);
 
        stmt.bind(dir);
@@ -277,6 +291,8 @@ void Manager::deleteLastScanTime(const std::string &dir)
 
 void Manager::cleanLastScanTime()
 {
+       std::lock_guard<std::mutex> l(this->m_mutex);
+
        Statement stmt(this->m_conn, Query::DEL_SCAN_REQUEST);
 
        stmt.exec();
@@ -287,6 +303,8 @@ void Manager::cleanLastScanTime()
 //===========================================================================
 RowShPtr Manager::getDetectedByNameOnPath(const std::string &path)
 {
+       std::lock_guard<std::mutex> l(this->m_mutex);
+
        Statement stmt(this->m_conn, Query::SEL_DETECTED_BY_NAME_ON_PATH);
        stmt.bind(path);
 
@@ -298,6 +316,8 @@ RowShPtr Manager::getDetectedByNameOnPath(const std::string &path)
 
 RowShPtr Manager::getDetectedCloudByNameOnPath(const std::string &path)
 {
+       std::lock_guard<std::mutex> l(this->m_mutex);
+
        Statement stmt(this->m_conn, Query::SEL_DETECTED_CLOUD_BY_NAME_ON_PATH);
        stmt.bind(path);
 
@@ -307,6 +327,31 @@ RowShPtr Manager::getDetectedCloudByNameOnPath(const std::string &path)
        return extractRowCloud(stmt);
 }
 
+RowShPtr Manager::getDetectedAllByNameOnPath(const std::string &path, bool *isByCloud)
+{
+       std::lock_guard<std::mutex> l(this->m_mutex);
+
+       Statement stmt(this->m_conn, Query::SEL_DETECTED_BY_NAME_ON_PATH);
+       stmt.bind(path);
+
+       if (stmt.step()) {
+               if (isByCloud)
+                       *isByCloud = false;
+               return extractRow(stmt);
+       }
+
+       Statement stmt2(this->m_conn, Query::SEL_DETECTED_CLOUD_BY_NAME_ON_PATH);
+       stmt.bind(path);
+
+       if (stmt2.step()) {
+               if (isByCloud)
+                       *isByCloud = true;
+               return extractRow(stmt);
+       }
+
+       return nullptr;
+}
+
 RowShPtrs Manager::getDetectedByNameOnDir(const std::string &dir)
 {
        Statement stmt(this->m_conn, Query::SEL_DETECTED_BY_NAME_ON_DIR);
@@ -334,8 +379,14 @@ RowShPtrs Manager::getDetectedCloudByNameOnDir(const std::string &dir)
 
 RowShPtrs Manager::getDetectedAllByNameOnDir(const std::string &dir)
 {
-       auto normals = this->getDetectedByNameOnDir(dir);
-       auto clouds = this->getDetectedCloudByNameOnDir(dir);
+       RowShPtrs normals;
+       RowShPtrs clouds;
+
+       {
+               std::lock_guard<std::mutex> l(this->m_mutex);
+               normals = this->getDetectedByNameOnDir(dir);
+               clouds = this->getDetectedCloudByNameOnDir(dir);
+       }
 
        if (clouds.empty())
                return normals;
@@ -369,6 +420,8 @@ RowShPtrs Manager::getDetectedAllByNameOnDir(const std::string &dir)
 
 RowShPtrs Manager::getDetectedByFilepathOnDir(const std::string &dir)
 {
+       std::lock_guard<std::mutex> l(this->m_mutex);
+
        Statement stmt(this->m_conn, Query::SEL_DETECTED_BY_FILEPATH_ON_DIR);
        stmt.bind(dir);
 
@@ -382,6 +435,8 @@ RowShPtrs Manager::getDetectedByFilepathOnDir(const std::string &dir)
 
 RowShPtr Manager::getWorstByPkgPath(const std::string &pkgPath)
 {
+       std::lock_guard<std::mutex> l(this->m_mutex);
+
        Statement stmt(this->m_conn, Query::SEL_WORST_BY_PKGPATH);
        stmt.bind(pkgPath);
 
@@ -403,6 +458,33 @@ RowShPtr Manager::getWorstByPkgPath(const std::string &pkgPath)
        return row;
 }
 
+void Manager::insertDetectedFile(const std::string &filepath, const CsDetected &d,
+                                                                const std::string &dataVersion)
+{
+       std::lock_guard<std::mutex> l(this->m_mutex);
+
+       this->insertName(filepath);
+       this->insertDetected(d, filepath, dataVersion);
+}
+
+void Manager::insertDetectedFileInApp(const std::string &pkgpath, const std::string &filepath,
+                                                                         const CsDetected &d, const std::string &dataVersion)
+{
+       std::lock_guard<std::mutex> l(this->m_mutex);
+
+       this->insertName(pkgpath);
+       this->insertDetected(d, filepath, dataVersion);
+}
+
+void Manager::insertDetectedAppByCloud(const std::string &name, const std::string &pkgId,
+                                                                          const CsDetected &d, const std::string &dataVersion)
+{
+       std::lock_guard<std::mutex> l(this->m_mutex);
+
+       this->insertName(name);
+       this->insertDetectedCloud(d, pkgId, name, dataVersion);
+}
+
 void Manager::insertName(const std::string &name)
 {
        Statement stmt(this->m_conn, Query::INS_NAME);
@@ -444,6 +526,8 @@ void Manager::insertDetectedCloud(const CsDetected &d, const std::string &pkgId,
 void Manager::insertWorst(const std::string &pkgId, const std::string &name,
                                                  const std::string &filepath)
 {
+       std::lock_guard<std::mutex> l(this->m_mutex);
+
        Statement stmt(this->m_conn, Query::INS_WORST);
 
        stmt.bind(pkgId);
@@ -454,6 +538,8 @@ void Manager::insertWorst(const std::string &pkgId, const std::string &name,
 
 void Manager::updateIgnoreFlag(const std::string &name, bool flag)
 {
+       std::lock_guard<std::mutex> l(this->m_mutex);
+
        Statement stmt(this->m_conn, Query::UPD_IGNORE);
 
        stmt.bind((flag ? 1 : 0));
@@ -463,6 +549,8 @@ void Manager::updateIgnoreFlag(const std::string &name, bool flag)
 
 void Manager::deleteDetectedByNameOnPath(const std::string &path)
 {
+       std::lock_guard<std::mutex> l(this->m_mutex);
+
        Statement stmt(this->m_conn, Query::DEL_DETECTED_BY_NAME_ON_PATH);
 
        stmt.bind(path);
@@ -471,6 +559,8 @@ void Manager::deleteDetectedByNameOnPath(const std::string &path)
 
 void Manager::deleteDetectedByFilepathOnPath(const std::string &path)
 {
+       std::lock_guard<std::mutex> l(this->m_mutex);
+
        Statement stmt(this->m_conn, Query::DEL_DETECTED_BY_FILEPATH_ON_PATH);
 
        stmt.bind(path);
@@ -480,6 +570,8 @@ void Manager::deleteDetectedByFilepathOnPath(const std::string &path)
 void Manager::deleteDetectedDeprecatedOnDir(const std::string &dir,
                                                                                        const std::string &dataVersion)
 {
+       std::lock_guard<std::mutex> l(this->m_mutex);
+
        Statement stmt(this->m_conn, Query::DEL_DETECTED_DEPRECATED_ON_DIR);
 
        stmt.bind(dir);
index 5cd8cf7..d128d90 100644 (file)
@@ -61,19 +61,19 @@ public:
        void cleanLastScanTime();
 
        // DETECTED_MALWARE_FILE & USER_RESPONSE
+       RowShPtr getDetectedAllByNameOnPath(const std::string &path, bool *isByCloud = nullptr);
        RowShPtr getDetectedByNameOnPath(const std::string &path);
        RowShPtr getDetectedCloudByNameOnPath(const std::string &path);
-       RowShPtrs getDetectedByNameOnDir(const std::string &dir);
-       RowShPtrs getDetectedCloudByNameOnDir(const std::string &dir);
        RowShPtrs getDetectedAllByNameOnDir(const std::string &dir);
        RowShPtrs getDetectedByFilepathOnDir(const std::string &dir);
        RowShPtr getWorstByPkgPath(const std::string &pkgPath);
 
-       void insertName(const std::string &name);
-       void insertDetected(const CsDetected &d, const std::string &filename,
-                                               const std::string &dataVersion);
-       void insertDetectedCloud(const CsDetected &d, const std::string &pkgId,
-                                                        const std::string &name, const std::string &dataVersion);
+       void insertDetectedFile(const std::string &filepath, const CsDetected &d,
+                                                       const std::string &dataVersion);
+       void insertDetectedFileInApp(const std::string &pkgpath, const std::string &filepath,
+                                                                const CsDetected &d, const std::string &dataVersion);
+       void insertDetectedAppByCloud(const std::string &name, const std::string &pkgId,
+                                                        const CsDetected &d, const std::string &dataVersion);
        void insertWorst(const std::string &pkgId, const std::string &name,
                                         const std::string &filepath);
 
@@ -84,6 +84,15 @@ public:
                                                                           const std::string &dataVersion);
 
 private:
+       RowShPtrs getDetectedByNameOnDir(const std::string &dir);
+       RowShPtrs getDetectedCloudByNameOnDir(const std::string &dir);
+
+       void insertName(const std::string &name);
+       void insertDetected(const CsDetected &d, const std::string &filename,
+                                               const std::string &dataVersion);
+       void insertDetectedCloud(const CsDetected &d, const std::string &pkgId,
+                                                        const std::string &name, const std::string &dataVersion);
+
        void resetDatabase();
        bool isTableExist(const std::string &name);
        std::string getScript(const std::string &scriptName);
@@ -95,6 +104,8 @@ private:
        std::string m_scriptsDir;
 
        std::map<csr_engine_id_e, csr_state_e> m_stateMap;
+       std::mutex m_stateMutex;
+
        std::mutex m_mutex;
 };
 
index 785653f..0004f61 100644 (file)
@@ -186,8 +186,7 @@ RawBuffer CsLogic::scanAppOnCloud(const CsContext &context,
        detected.isApp = true;
        detected.pkgId = pkgId;
 
-       this->m_db->insertName(pkgPath);
-       this->m_db->insertDetectedCloud(detected, pkgId, pkgPath, this->m_dataVersion);
+       this->m_db->insertDetectedAppByCloud(pkgPath, pkgId, detected, this->m_dataVersion);
 
        return this->handleAskUser(context, detected);
 }
@@ -228,8 +227,8 @@ CsDetectedPtr CsLogic::scanAppDelta(const std::string &pkgPath, const std::strin
                candidate.isApp = true;
                candidate.pkgId = pkgId;
 
-               this->m_db->insertName(pkgPath);
-               this->m_db->insertDetected(candidate, file->getPath(), this->m_dataVersion);
+               this->m_db->insertDetectedFileInApp(pkgPath, file->getPath(), candidate,
+                                                                                       this->m_dataVersion);
 
                if (!riskiest) {
                        riskiest.reset(new CsDetected(std::move(candidate)));
@@ -399,8 +398,7 @@ RawBuffer CsLogic::scanFileWithoutDelta(const CsContext &context,
 
        auto d = this->convert(result, filepath, timestamp);
 
-       this->m_db->insertName(d.targetName);
-       this->m_db->insertDetected(d, d.targetName, this->m_dataVersion);
+       this->m_db->insertDetectedFile(d.targetName, d, this->m_dataVersion);
 
        return this->handleAskUser(context, d, std::forward<FilePtr>(fileptr));
 }
@@ -564,19 +562,13 @@ RawBuffer CsLogic::judgeStatus(const std::string &filepath, csr_cs_action_e acti
 
        const auto &targetName = (file->isInApp() ? file->getAppPkgPath() : filepath);
 
-       auto history = this->m_db->getDetectedByNameOnPath(targetName);
-
        bool isCloudHistory = false;
 
-       if (!history) {
-               history = this->m_db->getDetectedCloudByNameOnPath(targetName);
-
-               if (!history) {
-                       ERROR("Target to be judged doesn't exist in db. name: " << targetName);
-                       return BinaryQueue::Serialize(CSR_ERROR_INVALID_PARAMETER).pop();
-               }
+       auto history = this->m_db->getDetectedAllByNameOnPath(targetName, &isCloudHistory);
 
-               isCloudHistory = true;
+       if (!history) {
+               ERROR("Target to be judged doesn't exist in db. name: " << targetName);
+               return BinaryQueue::Serialize(CSR_ERROR_INVALID_PARAMETER).pop();
        }
 
        // file create based on fileInAppPath(for app target, it is worst detected)
@@ -622,9 +614,7 @@ RawBuffer CsLogic::getDetected(const std::string &filepath)
                return BinaryQueue::Serialize(CSR_ERROR_NONE).pop();
        }
 
-       auto row = this->m_db->getDetectedByNameOnPath(target);
-       if (!row)
-               row = this->m_db->getDetectedCloudByNameOnPath(target);
+       auto row = this->m_db->getDetectedAllByNameOnPath(target);
 
        if (row && !row->isIgnored)
                return BinaryQueue::Serialize(CSR_ERROR_NONE, row).pop();
@@ -670,8 +660,6 @@ RawBuffer CsLogic::getIgnored(const std::string &filepath)
        }
 
        auto row = this->m_db->getDetectedByNameOnPath(target);
-       if (!row)
-               row = this->m_db->getDetectedCloudByNameOnPath(target);
 
        if (row && row->isIgnored)
                return BinaryQueue::Serialize(CSR_ERROR_NONE, row).pop();
index 4f83ef1..41611a3 100644 (file)
@@ -136,18 +136,16 @@ BOOST_AUTO_TEST_CASE(detected_malware_file)
        auto detected = db.getDetectedByNameOnPath(malware1.targetName);
        CHECK_IS_NULL(detected);
 
-       auto detectedList = db.getDetectedByNameOnDir("/opt");
+       auto detectedList = db.getDetectedAllByNameOnDir("/opt");
        ASSERT_IF(detectedList.empty(), true);
 
-       db.insertName(malware1.targetName);
-       db.insertDetected(malware1, malware1.targetName, initDataVersion);
+       db.insertDetectedFile(malware1.targetName, malware1, initDataVersion);
        detected = db.getDetectedByNameOnPath(malware1.targetName);
        checkSameMalware(malware1, *detected);
        ASSERT_IF(detected->dataVersion, initDataVersion);
        ASSERT_IF(detected->isIgnored, false);
 
-       db.insertName(malware2.targetName);
-       db.insertDetected(malware2, malware2.targetName, initDataVersion);
+       db.insertDetectedFile(malware2.targetName, malware2, initDataVersion);
        db.updateIgnoreFlag(malware2.targetName, true);
        detected = db.getDetectedByNameOnPath(malware2.targetName);
        checkSameMalware(malware2, *detected);
@@ -155,7 +153,7 @@ BOOST_AUTO_TEST_CASE(detected_malware_file)
        ASSERT_IF(detected->isIgnored, true);
 
        // getDetectedMalwares test
-       detectedList = db.getDetectedByNameOnDir("/opt");
+       detectedList = db.getDetectedAllByNameOnDir("/opt");
        ASSERT_IF(detectedList.size(), static_cast<size_t>(2));
 
        for (auto &item : detectedList) {
@@ -174,8 +172,7 @@ BOOST_AUTO_TEST_CASE(detected_malware_file)
        ASSERT_IF(detected->isIgnored, true);
 
        // deleteDeprecatedDetectedMalwares test
-       db.insertName(malware3.targetName);
-       db.insertDetected(malware3, malware3.targetName, changedDataVersion);
+       db.insertDetectedFile(malware3.targetName, malware3, changedDataVersion);
        db.deleteDetectedDeprecatedOnDir("/opt", changedDataVersion);
        detected = db.getDetectedByNameOnPath(malware3.targetName);
        checkSameMalware(malware3, *detected);