mv_machine_learning: fix mutex bug
authorInki Dae <inki.dae@samsung.com>
Tue, 28 Feb 2023 02:25:54 +0000 (11:25 +0900)
committerKwanghoon Son <k.son@samsung.com>
Fri, 3 Mar 2023 08:11:58 +0000 (17:11 +0900)
[Issue type] : bug fix

Fixed a mutex bug that race condition to context object happens due to using
a mutex per context. Context object should also be protected by mutex so
use a task group specific mutex instead of a mutex per a context.

Change-Id: I468d835f3758a905453c32124a75335de6bc8f8a
Signed-off-by: Inki Dae <inki.dae@samsung.com>
mv_machine_learning/common/include/context.h
mv_machine_learning/face_recognition/src/mv_face_recognition_open.cpp
mv_machine_learning/object_detection/src/mv_object_detection_open.cpp

index 3f9027c..e989f8a 100644 (file)
@@ -18,7 +18,6 @@
 #define __CONTEXT_H__
 
 #include <map>
-#include <mutex>
 #include "itask.h"
 
 namespace mediavision
@@ -34,7 +33,6 @@ public:
        {}
 
        std::map<std::string, void *> __tasks;
-       std::mutex _mutex;
 };
 } // namespace
 } // namespace
index 82b6757..25f508b 100644 (file)
@@ -17,6 +17,7 @@
 #include <algorithm>
 #include <dlog.h>
 #include <memory>
+#include <mutex>
 
 #include "face_recognition_adapter.h"
 #include "facenet_adapter.h"
@@ -32,6 +33,8 @@ using namespace mediavision::machine_learning::exception;
 using FaceRecognitionTask = ITask<FaceRecognitionInput, FaceRecognitionResult>;
 using FacenetTask = ITask<FacenetInput, FacenetOutput>;
 
+static mutex g_face_recognition_mutex;
+
 int mv_face_recognition_create_open(mv_face_recognition_h *handle)
 {
        if (!handle) {
@@ -90,6 +93,8 @@ int mv_face_recognition_create_open(mv_face_recognition_h *handle)
 
 int mv_face_recognition_destroy_open(mv_face_recognition_h handle)
 {
+       lock_guard<mutex> lock(g_face_recognition_mutex);
+
        if (!handle) {
                LOGE("Handle is NULL.");
                return MEDIA_VISION_ERROR_INVALID_PARAMETER;
@@ -121,6 +126,8 @@ int mv_face_recognition_prepare_open(mv_face_recognition_h handle)
 {
        LOGD("ENTER");
 
+       lock_guard<mutex> lock(g_face_recognition_mutex);
+
        if (!handle) {
                LOGE("Handle is NULL.");
                return MEDIA_VISION_ERROR_INVALID_PARAMETER;
@@ -131,8 +138,6 @@ int mv_face_recognition_prepare_open(mv_face_recognition_h handle)
                auto face_recognition_task = static_cast<FaceRecognitionTask *>(context->__tasks["face_recognition"]);
                auto facenet_task = static_cast<FacenetTask *>(context->__tasks["facenet"]);
 
-               std::lock_guard<std::mutex> lock(context->_mutex);
-
                face_recognition_task->configure();
                facenet_task->configure();
                face_recognition_task->prepare();
@@ -151,6 +156,8 @@ int mv_face_recognition_register_open(mv_face_recognition_h handle, mv_source_h
 {
        LOGD("ENTER");
 
+       lock_guard<mutex> lock(g_face_recognition_mutex);
+
        if (!handle) {
                LOGE("Handle is NULL.");
                return MEDIA_VISION_ERROR_INVALID_PARAMETER;
@@ -160,9 +167,6 @@ int mv_face_recognition_register_open(mv_face_recognition_h handle, mv_source_h
                Context *context = static_cast<Context *>(handle);
                auto face_recognition_task = static_cast<FaceRecognitionTask *>(context->__tasks["face_recognition"]);
                auto facenet_task = static_cast<FacenetTask *>(context->__tasks["facenet"]);
-
-               std::lock_guard<std::mutex> lock(context->_mutex);
-
                FacenetInput facenet_input = { { source } };
 
                facenet_task->setInput(facenet_input);
@@ -190,6 +194,8 @@ int mv_face_recognition_unregister_open(mv_face_recognition_h handle, const char
 {
        LOGD("ENTER");
 
+       lock_guard<mutex> lock(g_face_recognition_mutex);
+
        if (!handle) {
                LOGE("Handle is NULL.");
                return MEDIA_VISION_ERROR_INVALID_PARAMETER;
@@ -198,9 +204,6 @@ int mv_face_recognition_unregister_open(mv_face_recognition_h handle, const char
        try {
                Context *context = static_cast<Context *>(handle);
                auto face_recognition_task = static_cast<FaceRecognitionTask *>(context->__tasks["face_recognition"]);
-
-               std::lock_guard<std::mutex> lock(context->_mutex);
-
                FaceRecognitionInput input = { mode::DELETE };
 
                input.labels.clear();
@@ -221,6 +224,8 @@ int mv_face_recognition_inference_open(mv_face_recognition_h handle, mv_source_h
 {
        LOGD("ENTER");
 
+       lock_guard<mutex> lock(g_face_recognition_mutex);
+
        if (!handle) {
                LOGE("Handle is NULL.");
                return MEDIA_VISION_ERROR_INVALID_PARAMETER;
@@ -230,9 +235,6 @@ int mv_face_recognition_inference_open(mv_face_recognition_h handle, mv_source_h
                Context *context = static_cast<Context *>(handle);
                auto face_recognition_task = static_cast<FaceRecognitionTask *>(context->__tasks["face_recognition"]);
                auto facenet_task = static_cast<FacenetTask *>(context->__tasks["facenet"]);
-
-               std::lock_guard<std::mutex> lock(context->_mutex);
-
                FacenetInput facenet_input = { { source } };
 
                facenet_task->setInput(facenet_input);
@@ -258,6 +260,8 @@ int mv_face_recognition_get_label_open(mv_face_recognition_h handle, const char
 {
        LOGD("ENTER");
 
+       lock_guard<mutex> lock(g_face_recognition_mutex);
+
        if (!handle) {
                LOGE("Handle is NULL.");
                return MEDIA_VISION_ERROR_INVALID_PARAMETER;
@@ -267,8 +271,6 @@ int mv_face_recognition_get_label_open(mv_face_recognition_h handle, const char
                Context *context = static_cast<Context *>(handle);
                auto face_recognition_task = static_cast<FaceRecognitionTask *>(context->__tasks["face_recognition"]);
 
-               std::lock_guard<std::mutex> lock(context->_mutex);
-
                *out_label = face_recognition_task->getOutput().label.c_str();
        } catch (const BaseException &e) {
                LOGE("%s", e.what());
index 0c07f0b..384d67e 100644 (file)
@@ -26,6 +26,7 @@
 #include <unistd.h>
 #include <string>
 #include <algorithm>
+#include <mutex>
 
 using namespace std;
 using namespace mediavision::inference;
@@ -35,6 +36,8 @@ using namespace MediaVision::Common;
 using namespace mediavision::machine_learning::exception;
 using ObjectDetectionTask = ITask<ObjectDetectionInput, ObjectDetectionResult>;
 
+static mutex g_object_detection_mutex;
+
 int mv_object_detection_create_open(mv_object_detection_h *out_handle)
 {
        if (!out_handle) {
@@ -63,6 +66,8 @@ int mv_object_detection_create_open(mv_object_detection_h *out_handle)
 
 int mv_object_detection_destroy_open(mv_object_detection_h handle)
 {
+       lock_guard<mutex> lock(g_object_detection_mutex);
+
        if (!handle) {
                LOGE("Handle is NULL.");
                return MEDIA_VISION_ERROR_INVALID_PARAMETER;
@@ -70,8 +75,6 @@ int mv_object_detection_destroy_open(mv_object_detection_h handle)
 
        auto context = static_cast<Context *>(handle);
 
-       std::lock_guard<std::mutex> lock(context->_mutex);
-
        for (auto &m : context->__tasks)
                delete static_cast<ObjectDetectionTask *>(m.second);
 
@@ -85,6 +88,8 @@ int mv_object_detection_destroy_open(mv_object_detection_h handle)
 int mv_object_detection_set_model_open(mv_object_detection_h handle, const char *model_name, const char *model_file,
                                                                           const char *meta_file, const char *label_file)
 {
+       lock_guard<mutex> lock(g_object_detection_mutex);
+
        if (!handle) {
                LOGE("Handle is NULL.");
                return MEDIA_VISION_ERROR_INVALID_PARAMETER;
@@ -116,6 +121,8 @@ int mv_object_detection_configure_open(mv_object_detection_h handle)
 {
        LOGD("ENTER");
 
+       lock_guard<mutex> lock(g_object_detection_mutex);
+
        if (!handle) {
                LOGE("Handle is NULL.");
                return MEDIA_VISION_ERROR_INVALID_PARAMETER;
@@ -125,8 +132,6 @@ int mv_object_detection_configure_open(mv_object_detection_h handle)
                auto context = static_cast<Context *>(handle);
                auto task = static_cast<ObjectDetectionTask *>(context->__tasks.at("object_detection"));
 
-               std::lock_guard<std::mutex> lock(context->_mutex);
-
                task->create(static_cast<int>(ObjectDetectionTaskType::MOBILENET_V1_SSD));
                task->configure();
        } catch (const BaseException &e) {
@@ -143,6 +148,8 @@ int mv_object_detection_prepare_open(mv_object_detection_h handle)
 {
        LOGD("ENTER");
 
+       lock_guard<mutex> lock(g_object_detection_mutex);
+
        if (!handle) {
                LOGE("Handle is NULL.");
                return MEDIA_VISION_ERROR_INVALID_PARAMETER;
@@ -152,8 +159,6 @@ int mv_object_detection_prepare_open(mv_object_detection_h handle)
                auto context = static_cast<Context *>(handle);
                auto task = static_cast<ObjectDetectionTask *>(context->__tasks.at("object_detection"));
 
-               std::lock_guard<std::mutex> lock(context->_mutex);
-
                task->prepare();
        } catch (const BaseException &e) {
                LOGE("%s", e.what());
@@ -169,6 +174,8 @@ int mv_object_detection_inference_open(mv_object_detection_h handle, mv_source_h
 {
        LOGD("ENTER");
 
+       lock_guard<mutex> lock(g_object_detection_mutex);
+
        if (!handle) {
                LOGE("Handle is NULL.");
                return MEDIA_VISION_ERROR_INVALID_PARAMETER;
@@ -178,8 +185,6 @@ int mv_object_detection_inference_open(mv_object_detection_h handle, mv_source_h
                auto context = static_cast<Context *>(handle);
                auto task = static_cast<ObjectDetectionTask *>(context->__tasks.at("object_detection"));
 
-               std::lock_guard<std::mutex> lock(context->_mutex);
-
                ObjectDetectionInput input = { source };
 
                task->setInput(input);
@@ -200,6 +205,8 @@ int mv_object_detection_get_result_open(mv_object_detection_h handle, unsigned i
 {
        LOGD("ENTER");
 
+       lock_guard<mutex> lock(g_object_detection_mutex);
+
        if (!handle) {
                LOGE("Handle is NULL.");
                return MEDIA_VISION_ERROR_INVALID_PARAMETER;
@@ -209,8 +216,6 @@ int mv_object_detection_get_result_open(mv_object_detection_h handle, unsigned i
                auto context = static_cast<Context *>(handle);
                auto task = static_cast<ObjectDetectionTask *>(context->__tasks.at("object_detection"));
 
-               std::lock_guard<std::mutex> lock(context->_mutex);
-
                ObjectDetectionResult &result = task->getOutput();
                *number_of_objects = result.number_of_objects;
                *indices = result.indices.data();
@@ -233,6 +238,8 @@ int mv_object_detection_get_label_open(mv_object_detection_h handle, const unsig
 {
        LOGD("ENTER");
 
+       lock_guard<mutex> lock(g_object_detection_mutex);
+
        if (!handle) {
                LOGE("Handle is NULL.");
                return MEDIA_VISION_ERROR_INVALID_PARAMETER;
@@ -242,8 +249,6 @@ int mv_object_detection_get_label_open(mv_object_detection_h handle, const unsig
                auto context = static_cast<Context *>(handle);
                auto task = static_cast<ObjectDetectionTask *>(context->__tasks.at("object_detection"));
 
-               std::lock_guard<std::mutex> lock(context->_mutex);
-
                ObjectDetectionResult &result = task->getOutput();
 
                if (result.number_of_objects <= index)