task_manager: use raw pointer instead of shared_ptr 20/314020/4
authorInki Dae <inki.dae@samsung.com>
Thu, 4 Jul 2024 05:18:34 +0000 (14:18 +0900)
committerInki Dae <inki.dae@samsung.com>
Mon, 8 Jul 2024 02:11:00 +0000 (11:11 +0900)
Use unique_ptr and raw_pointer instead of shared_ptr.

With shared_ptr, we have to manage the pointers carefully
because memory leak can happen due to the cyclic dependency issue[1]
So use raw pointer instead.

[1] https://stackoverflow.com/questions/22185896/what-is-the-cyclic-dependency-issue-with-shared-ptr

Change-Id: I86b02537d9e8db0f970ad36def395a165a992a36
Signed-off-by: Inki Dae <inki.dae@samsung.com>
13 files changed:
services/auto_zoom/src/AutoZoom.cpp
services/task_manager/include/BridgeNode.h
services/task_manager/include/CallbackNode.h
services/task_manager/include/EndpointNode.h
services/task_manager/include/INode.h
services/task_manager/include/TaskManager.h
services/task_manager/include/TaskNode.h
services/task_manager/include/TrainingNode.h
services/task_manager/src/CallbackNode.cpp
services/task_manager/src/InferenceNode.cpp
services/task_manager/src/TaskManager.cpp
services/task_manager/src/TaskNode.cpp
test/services/test_task_manager.cpp

index 4cf8343e0965ad78a116ccdc5d7b1d1e24963d4a..2bae39cea429f7b11fdeb0d6daf1ddd392e62bef 100644 (file)
@@ -99,30 +99,23 @@ AutoZoom::AutoZoom()
        // In default, we will use Inference service factory for Mediavision to use Mediavision framework
        // for inference service. TODO. introduce meta config file approach later.
        auto factory = InferenceTaskFactory::instance().create("MvInferenceTaskFactory");
-       _taskManager = make_unique<TaskManager>();
-
-       auto face_detection_node = make_shared<InferenceNode>("face_detection");
 
-       face_detection_node->setInferenceTask(factory->createFaceDetection());
-       _taskManager->addNode(face_detection_node);
+       _taskManager = make_unique<TaskManager>();
 
-       auto bridge_node = make_shared<BridgeNode>("bridge_node");
+       auto face_detection_node = _taskManager->requestNewNode(NodeType::INFERENCE, "face_detection");
+       dynamic_cast<InferenceNode *>(face_detection_node)->setInferenceTask(factory->createFaceDetection());
 
+       auto bridge_node = _taskManager->requestNewNode(NodeType::BRIDGE, "bridge_node");
        bridge_node->addDependency(face_detection_node);
-       bridge_node->setCb(BridgeNodeCallback);
-       _taskManager->addNode(bridge_node);
+       dynamic_cast<BridgeNode *>(bridge_node)->setCb(BridgeNodeCallback);
 
-       auto face_recognition_node = make_shared<InferenceNode>("face_recognition_node");
-
-       face_recognition_node->setInferenceTask(factory->createFaceRecognition());
+       auto face_recognition_node = _taskManager->requestNewNode(NodeType::INFERENCE, "face_recognition_node");
+       dynamic_cast<InferenceNode *>(face_recognition_node)->setInferenceTask(factory->createFaceRecognition());
        face_recognition_node->addDependency(bridge_node);
-       _taskManager->addNode(face_recognition_node);
-
-       auto endpoint_node = make_shared<EndpointNode>("endpoint");
 
+       auto endpoint_node = _taskManager->requestNewNode(NodeType::ENDPOINT, "endpoint");
        endpoint_node->addDependency(face_detection_node);
        endpoint_node->addDependency(face_recognition_node);
-       _taskManager->addNode(endpoint_node);
 
        _postprocessor = make_unique<Postprocessor>();
 }
index 4ec596c5a52eec60e7e7b34b78fdd3b0749a2072..dfa8a189202d43da59c8cab5d9d30ef4a063ec7c 100644 (file)
@@ -47,7 +47,7 @@ public:
                _status = NodeStatus::INVALID;
                // If at least one dependency is valid, bridge node is valid.
                for (auto &dep : this->getDependencies()) {
-                       if (std::dynamic_pointer_cast<TaskNode>(dep)->getStatus() == NodeStatus::VALID) {
+                       if (dynamic_cast<TaskNode *>(dep)->getStatus() == NodeStatus::VALID) {
                                _status = NodeStatus::VALID;
                                break;
                        }
index 1cea5e61fd8a170575ac2c09009c6de4fef99de9..079cc266bfdaa7c04a0e8b8d373c8081283dc16b 100644 (file)
@@ -28,14 +28,14 @@ namespace singleo
 {
 namespace services
 {
-class CallbackNode : public INode, public std::enable_shared_from_this<CallbackNode>
+class CallbackNode : public INode
 {
 protected:
        NodeType _type { NodeType::NONE };
        NodeStatus _status { NodeStatus::NONE };
        std::string _name;
-       std::vector<std::shared_ptr<INode> > _dependencies;
-       std::vector<std::shared_ptr<INode> > _nexts;
+       std::vector<INode *> _dependencies;
+       std::vector<INode *> _nexts;
        NodeCb _cb;
        std::shared_ptr<SharedBuffer> _inputBuffer;
        std::shared_ptr<SharedBuffer> _outputBuffer;
@@ -44,8 +44,8 @@ protected:
        std::condition_variable _event;
        std::mutex _mutex;
 
-       bool isNodeDuplicated(const std::vector<std::shared_ptr<INode> > &target, const std::shared_ptr<INode> &newNode);
-       void addNext(std::shared_ptr<INode> node) override;
+       bool isNodeDuplicated(const std::vector<INode *> &target, const INode *newNode);
+       void addNext(INode *node) override;
 
 public:
        CallbackNode() = default;
@@ -60,9 +60,9 @@ public:
        }
        void setInputBuffer(std::shared_ptr<SharedBuffer> &inputBuffer) override;
        std::shared_ptr<SharedBuffer> &getInputBuffer() override;
-       void addDependency(std::shared_ptr<INode> node) override;
-       std::vector<std::shared_ptr<INode> > &getDependencies() override;
-       std::vector<std::shared_ptr<INode> > &getNexts() override;
+       void addDependency(INode *node) override;
+       std::vector<INode *> &getDependencies() override;
+       std::vector<INode *> &getNexts() override;
        void setOutputBuffer(std::shared_ptr<SharedBuffer> outputBuffer) override;
        std::shared_ptr<SharedBuffer> &getOutputBuffer() override;
        void wait() override;
index 6d137fe494a5cf033e2b616d84979769a2a87462..0c30e3ace88ef3b48ab3697b792ee8ce3f042d89 100644 (file)
@@ -43,7 +43,7 @@ public:
                _status = NodeStatus::INVALID;
                // If at least one dependency is valid, endpoint node is valid.
                for (auto &dep : this->getDependencies()) {
-                       if (std::dynamic_pointer_cast<TaskNode>(dep)->getStatus() == NodeStatus::VALID) {
+                       if (dynamic_cast<TaskNode *>(dep)->getStatus() == NodeStatus::VALID) {
                                _status = NodeStatus::VALID;
                                break;
                        }
index cdb59621772e97badf132a1714a2bf74aa468efe..46f947107d73a9fa07b6bcb7caaa10c84413fe2b 100644 (file)
@@ -43,10 +43,10 @@ public:
        virtual std::string &getName() = 0;
        virtual void setInputBuffer(std::shared_ptr<SharedBuffer> &inputBuffer) = 0;
        virtual std::shared_ptr<SharedBuffer> &getInputBuffer() = 0;
-       virtual void addDependency(std::shared_ptr<INode> node) = 0;
-       virtual void addNext(std::shared_ptr<INode> node) = 0;
-       virtual std::vector<std::shared_ptr<INode> > &getNexts() = 0;
-       virtual std::vector<std::shared_ptr<INode> > &getDependencies() = 0;
+       virtual void addDependency(INode *node) = 0;
+       virtual void addNext(INode *node) = 0;
+       virtual std::vector<INode *> &getNexts() = 0;
+       virtual std::vector<INode *> &getDependencies() = 0;
        virtual void setOutputBuffer(std::shared_ptr<SharedBuffer> outputBuffer) = 0;
        virtual std::shared_ptr<SharedBuffer> &getOutputBuffer() = 0;
        virtual void configure() = 0;
index 16761a0e192723df2b8e1fa57dcdd2bba8f9e221..4c8002356613c2b5d25637be21d7751d2c950b99 100644 (file)
@@ -36,24 +36,25 @@ class TaskManager
 {
 private:
        std::vector<std::shared_ptr<BaseDataType> > _inputs;
-       std::vector<std::shared_ptr<INode> > _nodes;
+       std::vector<INode *> _nodes;
        std::vector<std::shared_ptr<BaseResultType> > _results;
        std::queue<std::shared_ptr<std::thread> > _threads;
-       std::unordered_set<std::shared_ptr<INode> > _is_thread_created;
+       std::unordered_set<INode *> _is_thread_created;
 
        std::mutex _thread_mutex;
 
-       void threadCb(std::shared_ptr<INode> &node);
+       void addNode(INode *node);
+       void threadCb(INode *node);
        void verifyGraph();
-       bool isNodeDuplicated(const std::vector<std::shared_ptr<INode> > &target, const std::shared_ptr<INode> &newNode);
+       bool isNodeDuplicated(const std::vector<INode *> &target, const INode *newNode);
 
 public:
        TaskManager() = default;
        ~TaskManager() = default;
 
+       INode *requestNewNode(NodeType type, std::string nodeName);
        void addInput(BaseDataType &input);
        std::vector<std::shared_ptr<BaseDataType> > &getInputs();
-       void addNode(std::shared_ptr<INode> node);
        void run();
        std::vector<std::shared_ptr<BaseResultType> > &output();
        void clear();
index 97e407c03acba156bee6972b39ba28c89d61151f..f50a4f807d1e256204951803b8dcbb23ef45552d 100644 (file)
@@ -28,22 +28,22 @@ namespace singleo
 {
 namespace services
 {
-class TaskNode : public INode, public std::enable_shared_from_this<TaskNode>
+class TaskNode : public INode
 {
 protected:
        NodeType _type { NodeType::NONE };
        NodeStatus _status { NodeStatus::NONE };
        std::string _name;
-       std::vector<std::shared_ptr<INode> > _dependencies;
-       std::vector<std::shared_ptr<INode> > _nexts;
+       std::vector<INode *> _dependencies;
+       std::vector<INode *> _nexts;
        std::shared_ptr<SharedBuffer> _inputBuffer;
        std::shared_ptr<SharedBuffer> _outputBuffer;
        bool _completed { false };
        std::condition_variable _event;
        std::mutex _mutex;
 
-       bool isNodeDuplicated(const std::vector<std::shared_ptr<INode> > &target, const std::shared_ptr<INode> &newNode);
-       void addNext(std::shared_ptr<INode> node) override;
+       bool isNodeDuplicated(const std::vector<INode *> &target, const INode *newNode);
+       void addNext(INode *node) override;
 
 public:
        TaskNode() = default;
@@ -58,9 +58,9 @@ public:
        }
        void setInputBuffer(std::shared_ptr<SharedBuffer> &inputBuffer) override;
        std::shared_ptr<SharedBuffer> &getInputBuffer() override;
-       void addDependency(std::shared_ptr<INode> node) override;
-       std::vector<std::shared_ptr<INode> > &getDependencies() override;
-       std::vector<std::shared_ptr<INode> > &getNexts() override;
+       void addDependency(INode *node) override;
+       std::vector<INode *> &getDependencies() override;
+       std::vector<INode *> &getNexts() override;
        void setOutputBuffer(std::shared_ptr<SharedBuffer> outputBuffer) override;
        std::shared_ptr<SharedBuffer> &getOutputBuffer() override;
        void wait() override;
index 16ddaa06eb6d3820231eba9dfdc253add0aa19bb..edb815e4f52a70910902165c42f91bcbea0a41af 100644 (file)
@@ -31,6 +31,7 @@ namespace services
 class TrainingNode : public TaskNode
 {
 private:
+       std::vector<std::shared_ptr<BaseResultType> > _results;
        // TODO. define ITrainingTaskInterface here.
 
 public:
@@ -51,9 +52,10 @@ public:
                // TODO. implement invoke here.
        }
 
-       std::vector<std::shared_ptr<BaseResultType> > &results()
+       std::vector<std::shared_ptr<BaseResultType> > &results() final
        {
                // TODO. implement results here.
+               return _results;
        }
 };
 
index 6374028a5b7117384f8c953ba671c009b72fa591..0c7814bcf2a2db7babf24da8e7852b1e04b225f3 100644 (file)
@@ -58,13 +58,13 @@ void CallbackNode::setCb(const NodeCb &cb)
        _cb = cb;
 }
 
-bool CallbackNode::isNodeDuplicated(const vector<shared_ptr<INode> > &target, const shared_ptr<INode> &newNode)
+bool CallbackNode::isNodeDuplicated(const vector<INode *> &target, const INode *newNode)
 {
-       return find_if(target.begin(), target.end(),
-                                  [&newNode](const shared_ptr<INode> &node) { return node == newNode; }) != target.end();
+       return find_if(target.begin(), target.end(), [&newNode](const INode *node) { return node == newNode; }) !=
+                  target.end();
 }
 
-void CallbackNode::addDependency(std::shared_ptr<INode> node)
+void CallbackNode::addDependency(INode *node)
 {
        if (isNodeDuplicated(_dependencies, node)) {
                SINGLEO_LOGE("A given node has already been registered.");
@@ -72,15 +72,15 @@ void CallbackNode::addDependency(std::shared_ptr<INode> node)
        }
 
        _dependencies.push_back(node);
-       node->addNext(shared_ptr<INode>(shared_from_this()));
+       node->addNext(this);
 }
 
-std::vector<std::shared_ptr<INode> > &CallbackNode::getDependencies()
+std::vector<INode *> &CallbackNode::getDependencies()
 {
        return _dependencies;
 }
 
-void CallbackNode::addNext(shared_ptr<INode> node)
+void CallbackNode::addNext(INode *node)
 {
        if (isNodeDuplicated(_nexts, node)) {
                SINGLEO_LOGE("A given node has already been registered.");
@@ -90,7 +90,7 @@ void CallbackNode::addNext(shared_ptr<INode> node)
        _nexts.push_back(node);
 }
 
-std::vector<std::shared_ptr<INode> > &CallbackNode::getNexts()
+std::vector<INode *> &CallbackNode::getNexts()
 {
        return _nexts;
 }
index 4dd7354c77db27de0644e68aa00ae155f3a69b55..df367a85c98bcd5491ce96b1b36c50e1b650ef2e 100644 (file)
@@ -28,6 +28,8 @@ namespace services
 void InferenceNode::setInferenceTask(unique_ptr<inference::IInferenceTaskInterface> &&task)
 {
        _task = move(task);
+
+       configure();
 }
 
 void InferenceNode::configure()
@@ -43,7 +45,7 @@ void InferenceNode::invoke()
 
        // Note: Inference node can have at max one dependency.
        for (auto &dep : this->getDependencies()) {
-               if (dynamic_pointer_cast<CallbackNode>(dep)->getStatus() == NodeStatus::INVALID) {
+               if (dynamic_cast<CallbackNode *>(dep)->getStatus() == NodeStatus::INVALID) {
                        _status = NodeStatus::INVALID;
                        return;
                }
index 7272f070f005a5d8d36134eee8747040ebb6516b..cbf7f3bbd9d1c599a06188c60a3ce206e181f4d7 100644 (file)
@@ -26,6 +26,7 @@
 #include "BridgeNode.h"
 #include "BranchNode.h"
 #include "EndpointNode.h"
+#include "TrainingNode.h"
 
 using namespace std;
 using namespace singleo::exception;
@@ -34,7 +35,36 @@ namespace singleo
 {
 namespace services
 {
-void TaskManager::threadCb(shared_ptr<INode> &node)
+INode *TaskManager::requestNewNode(NodeType type, std::string nodeName)
+{
+       INode *node = nullptr;
+
+       switch (type) {
+       case NodeType::BRANCH:
+               node = new BranchNode(nodeName);
+               break;
+       case NodeType::BRIDGE:
+               node = new BridgeNode(nodeName);
+               break;
+       case NodeType::ENDPOINT:
+               node = new EndpointNode(nodeName);
+               break;
+       case NodeType::INFERENCE:
+               node = new InferenceNode(nodeName);
+               break;
+       case NodeType::TRAINING:
+               node = new TrainingNode(nodeName);
+               break;
+       default:
+               throw InvalidParameter("Node type not supported.");
+       }
+
+       addNode(node);
+
+       return node;
+}
+
+void TaskManager::threadCb(INode *node)
 {
        // Wait until all nodes added to this node as dependency are completed
        for (auto &d : node->getDependencies())
@@ -106,13 +136,13 @@ vector<shared_ptr<BaseDataType> > &TaskManager::getInputs()
        return _inputs;
 }
 
-bool TaskManager::isNodeDuplicated(const vector<shared_ptr<INode> > &target, const shared_ptr<INode> &newNode)
+bool TaskManager::isNodeDuplicated(const vector<INode *> &target, const INode *newNode)
 {
-       return find_if(target.begin(), target.end(),
-                                  [&newNode](const shared_ptr<INode> &node) { return node == newNode; }) != target.end();
+       return find_if(target.begin(), target.end(), [&newNode](const INode *node) { return node == newNode; }) !=
+                  target.end();
 }
 
-void TaskManager::addNode(std::shared_ptr<INode> node)
+void TaskManager::addNode(INode *node)
 {
        if (isNodeDuplicated(_nodes, node)) {
                SINGLEO_LOGE("A given node has already been registered.");
@@ -120,7 +150,6 @@ void TaskManager::addNode(std::shared_ptr<INode> node)
        }
 
        _nodes.push_back(node);
-       node->configure();
 }
 
 void TaskManager::verifyGraph()
@@ -150,7 +179,7 @@ void TaskManager::verifyGraph()
        }
        node_names.clear();
 
-       map<shared_ptr<INode>, unsigned int> degreeMap;
+       map<INode *, unsigned int> degreeMap;
 
        // Verify graph rule.
        for (auto &node : _nodes) {
@@ -207,7 +236,7 @@ void TaskManager::verifyGraph()
        }
 
        // Verify if _nodes is DAG(Directed Acyclic Graph) or not.
-       queue<shared_ptr<INode> > zeroDegreeQ;
+       queue<INode *> zeroDegreeQ;
 
        for (auto &node : _nodes)
                if (degreeMap[node] == 0)
@@ -304,6 +333,8 @@ vector<shared_ptr<BaseResultType> > &TaskManager::output()
 void TaskManager::clear()
 {
        _inputs.clear();
+       for (auto node : _nodes)
+               delete node;
        _nodes.clear();
        _results.clear();
        _is_thread_created.clear();
index e280746af51844ca0273ba92488b4c54fa891964..db6342e57b49f24b1dd0b26917aa8ed130103a58 100644 (file)
@@ -52,13 +52,13 @@ shared_ptr<SharedBuffer> &TaskNode::getInputBuffer()
        return _inputBuffer;
 }
 
-bool TaskNode::isNodeDuplicated(const vector<shared_ptr<INode> > &target, const shared_ptr<INode> &newNode)
+bool TaskNode::isNodeDuplicated(const vector<INode *> &target, const INode *newNode)
 {
-       return find_if(target.begin(), target.end(),
-                                  [&newNode](const shared_ptr<INode> &node) { return node == newNode; }) != target.end();
+       return find_if(target.begin(), target.end(), [&newNode](const INode *node) { return node == newNode; }) !=
+                  target.end();
 }
 
-void TaskNode::addDependency(std::shared_ptr<INode> node)
+void TaskNode::addDependency(INode *node)
 {
        if (isNodeDuplicated(_dependencies, node)) {
                SINGLEO_LOGE("A given node has already been registered.");
@@ -66,15 +66,15 @@ void TaskNode::addDependency(std::shared_ptr<INode> node)
        }
 
        _dependencies.push_back(node);
-       node->addNext(shared_ptr<INode>(shared_from_this()));
+       node->addNext(this);
 }
 
-std::vector<std::shared_ptr<INode> > &TaskNode::getDependencies()
+std::vector<INode *> &TaskNode::getDependencies()
 {
        return _dependencies;
 }
 
-void TaskNode::addNext(shared_ptr<INode> node)
+void TaskNode::addNext(INode *node)
 {
        if (isNodeDuplicated(_nexts, node)) {
                SINGLEO_LOGE("A given node has already been registered.");
@@ -84,7 +84,7 @@ void TaskNode::addNext(shared_ptr<INode> node)
        _nexts.push_back(node);
 }
 
-std::vector<std::shared_ptr<INode> > &TaskNode::getNexts()
+std::vector<INode *> &TaskNode::getNexts()
 {
        return _nexts;
 }
index 84d0d271f67adc35db99447c951118c3ab409a32..d16b607e3469c4cbfc2a1789559b7530d30a9654 100644 (file)
@@ -91,23 +91,19 @@ TEST(SingloTaskManager, MultipleNodesBasedGraphAShouldWork)
        for (unsigned int cnt = 0; cnt < maxIteration; ++cnt) {
                taskManager->addInput(image_data);
 
-               auto face_detection_node = make_shared<InferenceNode>("face_detection");
-               face_detection_node->setInferenceTask(factory->createFaceDetection());
-               taskManager->addNode(face_detection_node);
+               auto face_detection_node = taskManager->requestNewNode(NodeType::INFERENCE, "face_detection");
+               dynamic_cast<InferenceNode *>(face_detection_node)->setInferenceTask(factory->createFaceDetection());
 
-               auto bridge_node = make_shared<BridgeNode>("bridge");
-               bridge_node->setCb(BridgeNodeCallbackFD);
+               auto bridge_node = taskManager->requestNewNode(NodeType::BRIDGE, "bridge");
+               dynamic_cast<BridgeNode *>(bridge_node)->setCb(BridgeNodeCallbackFD);
                bridge_node->addDependency(face_detection_node);
-               taskManager->addNode(bridge_node);
 
-               auto face_landmark_node = make_shared<InferenceNode>("face_landmark");
-               face_landmark_node->setInferenceTask(factory->createFaceLandmarkDetection());
+               auto face_landmark_node = taskManager->requestNewNode(NodeType::INFERENCE, "face_landmark");
+               dynamic_cast<InferenceNode *>(face_landmark_node)->setInferenceTask(factory->createFaceLandmarkDetection());
                face_landmark_node->addDependency(bridge_node);
-               taskManager->addNode(face_landmark_node);
 
-               auto endpoint_node = make_shared<EndpointNode>("endpoint");
+               auto endpoint_node = taskManager->requestNewNode(NodeType::ENDPOINT, "endpoint");
                endpoint_node->addDependency(face_landmark_node);
-               taskManager->addNode(endpoint_node);
 
                taskManager->run();
 
@@ -153,28 +149,23 @@ TEST(SingloTaskManager, MultipleNodesBasedGraphBShouldWork)
        for (unsigned int cnt = 0; cnt < maxIteration; ++cnt) {
                taskManager->addInput(image_data);
 
-               auto face_detection_node_a = make_shared<InferenceNode>("face_detectionA");
-               face_detection_node_a->setInferenceTask(factory->createFaceDetection());
-               taskManager->addNode(face_detection_node_a);
+               auto face_detection_node_a = taskManager->requestNewNode(NodeType::INFERENCE, "face_detectionA");
+               dynamic_cast<InferenceNode *>(face_detection_node_a)->setInferenceTask(factory->createFaceDetection());
 
-               auto face_detection_node_b = make_shared<InferenceNode>("face_detectionB");
-               face_detection_node_b->setInferenceTask(factory->createFaceDetection());
-               taskManager->addNode(face_detection_node_b);
+               auto face_detection_node_b = taskManager->requestNewNode(NodeType::INFERENCE, "face_detectionB");
+               dynamic_cast<InferenceNode *>(face_detection_node_b)->setInferenceTask(factory->createFaceDetection());
 
-               auto bridge_node = make_shared<BridgeNode>("bridge");
-               bridge_node->setCb(BridgeNodeCallbackFD);
+               auto bridge_node = taskManager->requestNewNode(NodeType::BRIDGE, "bridge");
+               dynamic_cast<BridgeNode *>(bridge_node)->setCb(BridgeNodeCallbackFD);
                bridge_node->addDependency(face_detection_node_a);
                bridge_node->addDependency(face_detection_node_b);
-               taskManager->addNode(bridge_node);
 
-               auto face_landmark_node = make_shared<InferenceNode>("face_landmark");
-               face_landmark_node->setInferenceTask(factory->createFaceLandmarkDetection());
+               auto face_landmark_node = taskManager->requestNewNode(NodeType::INFERENCE, "face_landmark");
+               dynamic_cast<InferenceNode *>(face_landmark_node)->setInferenceTask(factory->createFaceLandmarkDetection());
                face_landmark_node->addDependency(bridge_node);
-               taskManager->addNode(face_landmark_node);
 
-               auto endpoint_node = make_shared<EndpointNode>("endpoint");
-               endpoint_node->addDependency(face_landmark_node);
-               taskManager->addNode(endpoint_node);
+               auto endpoint_node = taskManager->requestNewNode(NodeType::ENDPOINT, "endpoint");
+               dynamic_cast<EndpointNode *>(endpoint_node)->addDependency(face_landmark_node);
 
                taskManager->run();
 
@@ -232,25 +223,21 @@ TEST(SingloTaskManager, MultipleNodesBasedGraphCShouldWork)
        for (unsigned int cnt = 0; cnt < maxIteration; ++cnt) {
                taskManager->addInput(image_data);
 
-               auto face_detection_node = make_shared<InferenceNode>("face_detection");
-               face_detection_node->setInferenceTask(factory->createFaceDetection());
-               taskManager->addNode(face_detection_node);
+               auto face_detection_node = taskManager->requestNewNode(NodeType::INFERENCE, "face_detection");
+               dynamic_cast<InferenceNode *>(face_detection_node)->setInferenceTask(factory->createFaceDetection());
 
-               auto bridge_node = make_shared<BridgeNode>("bridge");
-               bridge_node->setCb(BridgeNodeCallbackFD);
+               auto bridge_node = taskManager->requestNewNode(NodeType::BRIDGE, "bridge");
+               dynamic_cast<BridgeNode *>(bridge_node)->setCb(BridgeNodeCallbackFD);
                bridge_node->addDependency(face_detection_node);
-               taskManager->addNode(bridge_node);
 
-               auto face_landmark_node = make_shared<InferenceNode>("face_landmark");
-               face_landmark_node->setInferenceTask(factory->createFaceLandmarkDetection());
+               auto face_landmark_node = taskManager->requestNewNode(NodeType::INFERENCE, "face_landmark");
+               dynamic_cast<InferenceNode *>(face_landmark_node)->setInferenceTask(factory->createFaceLandmarkDetection());
                face_landmark_node->addDependency(bridge_node);
-               taskManager->addNode(face_landmark_node);
 
-               auto endpoint_node = make_shared<EndpointNode>("endpoint");
-               endpoint_node->setCb(LastNodeCallback);
+               auto endpoint_node = taskManager->requestNewNode(NodeType::ENDPOINT, "endpoint");
+               dynamic_cast<EndpointNode *>(endpoint_node)->setCb(LastNodeCallback);
                endpoint_node->addDependency(face_detection_node);
                endpoint_node->addDependency(face_landmark_node);
-               taskManager->addNode(endpoint_node);
 
                taskManager->run();
 
@@ -309,30 +296,25 @@ TEST(SingloTaskManager, MultipleNodesBasedGraphDShouldWork)
        for (unsigned int cnt = 0; cnt < maxIteration; ++cnt) {
                taskManager->addInput(image_data);
 
-               auto face_detection_node_a = make_shared<InferenceNode>("face_detection_a");
-               face_detection_node_a->setInferenceTask(factory->createFaceDetection());
-               taskManager->addNode(face_detection_node_a);
+               auto face_detection_node_a = taskManager->requestNewNode(NodeType::INFERENCE, "face_detection_a");
+               dynamic_cast<InferenceNode *>(face_detection_node_a)->setInferenceTask(factory->createFaceDetection());
 
-               auto bridge_node = make_shared<BridgeNode>("bridge");
-               bridge_node->setCb(BridgeNodeCallbackFD);
+               auto bridge_node = taskManager->requestNewNode(NodeType::BRIDGE, "bridge");
+               dynamic_cast<BridgeNode *>(bridge_node)->setCb(BridgeNodeCallbackFD);
                bridge_node->addDependency(face_detection_node_a);
-               taskManager->addNode(bridge_node);
 
-               auto face_landmark_node = make_shared<InferenceNode>("face_landmark");
-               face_landmark_node->setInferenceTask(factory->createFaceLandmarkDetection());
+               auto face_landmark_node = taskManager->requestNewNode(NodeType::INFERENCE, "face_landmark");
+               dynamic_cast<InferenceNode *>(face_landmark_node)->setInferenceTask(factory->createFaceLandmarkDetection());
                face_landmark_node->addDependency(bridge_node);
-               taskManager->addNode(face_landmark_node);
 
-               auto face_detection_node_b = make_shared<InferenceNode>("face_detection_b");
-               face_detection_node_b->setInferenceTask(factory->createFaceDetection());
+               auto face_detection_node_b = taskManager->requestNewNode(NodeType::INFERENCE, "face_detection_b");
+               dynamic_cast<InferenceNode *>(face_detection_node_b)->setInferenceTask(factory->createFaceDetection());
                face_detection_node_b->addDependency(bridge_node);
-               taskManager->addNode(face_detection_node_b);
 
-               auto endpoint_node = make_shared<EndpointNode>("endpoint");
-               endpoint_node->setCb(LastNodeCallback);
+               auto endpoint_node = taskManager->requestNewNode(NodeType::ENDPOINT, "endpoint");
+               dynamic_cast<EndpointNode *>(endpoint_node)->setCb(LastNodeCallback);
                endpoint_node->addDependency(face_detection_node_b);
                endpoint_node->addDependency(face_landmark_node);
-               taskManager->addNode(endpoint_node);
 
                taskManager->run();
 
@@ -447,36 +429,32 @@ TEST(SingloTaskManager, MultipleNodesBasedGraphEShouldWork)
        for (unsigned int cnt = 0; cnt < maxIteration; ++cnt) {
                taskManager->addInput(image_data);
 
-               auto object_detection_node = make_shared<InferenceNode>("object_detection");
-               object_detection_node->setInferenceTask(factory->createObjectDetection());
-               taskManager->addNode(object_detection_node);
+               auto object_detection_node = taskManager->requestNewNode(NodeType::INFERENCE, "object_detection");
+               dynamic_cast<InferenceNode *>(object_detection_node)->setInferenceTask(factory->createObjectDetection());
 
-               auto bridge_node_1 = make_shared<BridgeNode>("bridge_1");
-               bridge_node_1->setCb(BridgeNodeCallbackOD);
+               auto bridge_node_1 = taskManager->requestNewNode(NodeType::BRIDGE, "bridge_1");
+               dynamic_cast<BridgeNode *>(bridge_node_1)->setCb(BridgeNodeCallbackOD);
                bridge_node_1->addDependency(object_detection_node);
-               taskManager->addNode(bridge_node_1);
 
-               auto image_classification_node_1 = make_shared<InferenceNode>("image_classification_1");
-               image_classification_node_1->setInferenceTask(factory->createImageClassification());
+               auto image_classification_node_1 = taskManager->requestNewNode(NodeType::INFERENCE, "image_classification_1");
+               dynamic_cast<InferenceNode *>(image_classification_node_1)
+                               ->setInferenceTask(factory->createImageClassification());
                image_classification_node_1->addDependency(bridge_node_1);
-               taskManager->addNode(image_classification_node_1);
 
-               auto bridge_node_2 = make_shared<BridgeNode>("bridge_2");
-               bridge_node_2->setCb(BridgeNodeCallbackIC);
+               auto bridge_node_2 = taskManager->requestNewNode(NodeType::BRIDGE, "bridge_2");
+               dynamic_cast<BridgeNode *>(bridge_node_2)->setCb(BridgeNodeCallbackIC);
                bridge_node_2->addDependency(image_classification_node_1);
-               taskManager->addNode(bridge_node_2);
 
-               auto image_classification_node_2 = make_shared<InferenceNode>("image_classification_2");
-               image_classification_node_2->setInferenceTask(factory->createImageClassification());
+               auto image_classification_node_2 = taskManager->requestNewNode(NodeType::INFERENCE, "image_classification_2");
+               dynamic_cast<InferenceNode *>(image_classification_node_2)
+                               ->setInferenceTask(factory->createImageClassification());
                image_classification_node_2->addDependency(bridge_node_2);
-               taskManager->addNode(image_classification_node_2);
 
                int endpoint_node_run = 0;
-               auto endpoint_node = make_shared<EndpointNode>("endpoint");
+               auto endpoint_node = taskManager->requestNewNode(NodeType::ENDPOINT, "endpoint");
                endpoint_node->addDependency(object_detection_node);
                endpoint_node->addDependency(image_classification_node_2);
-               endpoint_node->setCb([&](INode *node) { endpoint_node_run += 1; });
-               taskManager->addNode(endpoint_node);
+               dynamic_cast<EndpointNode *>(endpoint_node)->setCb([&](INode *node) { endpoint_node_run += 1; });
 
                taskManager->run();
 
@@ -488,7 +466,6 @@ TEST(SingloTaskManager, MultipleNodesBasedGraphEShouldWork)
 
 void BranchNodeCallback(INode *node)
 {
-       static ResultType result_type;
        auto branchNode = dynamic_cast<BranchNode *>(node);
        auto &inputBuffer = branchNode->getInputBuffer();
        auto newBaseData = inputBuffer->getInputs()[0]->clone();
@@ -550,34 +527,30 @@ TEST(SingloTaskManager, MultipleNodesBasedGraphFShouldWork)
                for (unsigned int cnt = 0; cnt < maxIteration; ++cnt) {
                        taskManager->addInput(image_data);
 
-                       auto face_detection_node = make_shared<InferenceNode>("face_detection");
-                       face_detection_node->setInferenceTask(factory->createFaceDetection());
-                       taskManager->addNode(face_detection_node);
+                       auto face_detection_node = taskManager->requestNewNode(NodeType::INFERENCE, "face_detection");
+                       dynamic_cast<InferenceNode *>(face_detection_node)->setInferenceTask(factory->createFaceDetection());
 
-                       auto object_detection_node = make_shared<InferenceNode>("object_detection");
-                       object_detection_node->setInferenceTask(factory->createObjectDetection());
-                       taskManager->addNode(object_detection_node);
+                       auto object_detection_node = taskManager->requestNewNode(NodeType::INFERENCE, "object_detection");
+                       dynamic_cast<InferenceNode *>(object_detection_node)->setInferenceTask(factory->createObjectDetection());
 
-                       auto branch_node = make_shared<BranchNode>("branch");
-                       branch_node->setCb(BranchNodeCallback);
+                       auto branch_node = taskManager->requestNewNode(NodeType::BRANCH, "branch");
+                       dynamic_cast<BranchNode *>(branch_node)->setCb(BranchNodeCallback);
                        branch_node->addDependency(face_detection_node);
                        branch_node->addDependency(object_detection_node);
-                       taskManager->addNode(branch_node);
 
-                       auto face_landmark_node = make_shared<InferenceNode>("face_landmark");
-                       face_landmark_node->setInferenceTask(factory->createFaceLandmarkDetection());
+                       auto face_landmark_node = taskManager->requestNewNode(NodeType::INFERENCE, "face_landmark");
+                       dynamic_cast<InferenceNode *>(face_landmark_node)->setInferenceTask(factory->createFaceLandmarkDetection());
                        face_landmark_node->addDependency(branch_node);
-                       taskManager->addNode(face_landmark_node);
 
-                       auto image_classification_node = make_shared<InferenceNode>("image_classification");
-                       image_classification_node->setInferenceTask(factory->createImageClassification());
+                       auto image_classification_node = taskManager->requestNewNode(NodeType::INFERENCE, "image_classification");
+                       dynamic_cast<InferenceNode *>(image_classification_node)
+                                       ->setInferenceTask(factory->createImageClassification());
                        image_classification_node->addDependency(branch_node);
-                       taskManager->addNode(image_classification_node);
 
-                       auto endpoint_node = make_shared<EndpointNode>("endpoint");
+                       auto endpoint_node = taskManager->requestNewNode(NodeType::ENDPOINT, "endpoint");
                        endpoint_node->addDependency(face_landmark_node);
                        endpoint_node->addDependency(image_classification_node);
-                       endpoint_node->setCb([&](INode *node) {
+                       dynamic_cast<EndpointNode *>(endpoint_node)->setCb([&](INode *node) {
                                auto results = node->results();
 
                                for (auto &result : results) {
@@ -598,8 +571,6 @@ TEST(SingloTaskManager, MultipleNodesBasedGraphFShouldWork)
                                }
                        });
 
-                       taskManager->addNode(endpoint_node);
-
                        taskManager->run();
                        taskManager->clear();
                }