From 9737919046bdd8b7b8e31316639b97205b5f69bf Mon Sep 17 00:00:00 2001 From: Jaeyun Jung Date: Mon, 20 Jan 2025 16:46:29 +0900 Subject: [PATCH] [Android] include database Separate node info for pipeline, and include mlops database based on sqlite to build android library. Signed-off-by: Jaeyun Jung --- daemon/main.c | 7 +- daemon/meson.build | 1 + daemon/mlops-agent-android.c | 40 ++--- daemon/mlops-agent-interface.c | 5 +- daemon/mlops-agent-internal.c | 37 +++++ daemon/mlops-agent-internal.h | 10 ++ daemon/mlops-agent-node.c | 284 +++++++++++++++++++++++++++++++++ daemon/mlops-agent-node.h | 71 +++++++++ daemon/pipeline-dbus-impl.cc | 198 +---------------------- daemon/service-db-util.h | 1 + jni/mlops-agent.mk | 6 +- 11 files changed, 444 insertions(+), 216 deletions(-) create mode 100755 daemon/mlops-agent-internal.c create mode 100755 daemon/mlops-agent-node.c create mode 100755 daemon/mlops-agent-node.h diff --git a/daemon/main.c b/daemon/main.c index 85ae7f9..2f5a934 100644 --- a/daemon/main.c +++ b/daemon/main.c @@ -21,7 +21,7 @@ #include "gdbus-util.h" #include "log.h" #include "dbus-interface.h" -#include "service-db-util.h" +#include "mlops-agent-internal.h" static GMainLoop *g_mainloop = NULL; static gboolean verbose = FALSE; @@ -112,7 +112,8 @@ main (int argc, char **argv) /* path to database */ if (!db_path) db_path = g_strdup (DB_PATH); - svcdb_initialize (db_path); + + ml_agent_initialize (db_path); g_mainloop = g_main_loop_new (NULL, FALSE); gdbus_get_system_connection (is_session); @@ -129,7 +130,7 @@ main (int argc, char **argv) g_mainloop = NULL; error: - svcdb_finalize (); + ml_agent_finalize (); is_session = verbose = FALSE; g_free (db_path); diff --git a/daemon/meson.build b/daemon/meson.build index 71c0056..5af8f01 100644 --- a/daemon/meson.build +++ b/daemon/meson.build @@ -1,6 +1,7 @@ # Machine Learning Agent ml_agent_incs = include_directories('.', 'include') ml_agent_lib_srcs = files('modules.c', 'gdbus-util.c', 'mlops-agent-interface.c', + 'mlops-agent-internal.c', 'mlops-agent-node.c', 'pipeline-dbus-impl.cc', 'model-dbus-impl.cc', 'resource-dbus-impl.cc', 'service-db.cc') ml_agent_deps = [ diff --git a/daemon/mlops-agent-android.c b/daemon/mlops-agent-android.c index 37b391c..48cf00c 100644 --- a/daemon/mlops-agent-android.c +++ b/daemon/mlops-agent-android.c @@ -15,6 +15,8 @@ #include "log.h" #include "mlops-agent-interface.h" #include "mlops-agent-internal.h" +#include "mlops-agent-node.h" +#include "service-db-util.h" /** * @brief An interface exported for setting the description of a pipeline. @@ -26,7 +28,7 @@ ml_agent_pipeline_set_description (const char *name, const char *pipeline_desc) g_return_val_if_reached (-EINVAL); } - return 0; + return svcdb_pipeline_set (name, pipeline_desc); } /** @@ -39,7 +41,7 @@ ml_agent_pipeline_get_description (const char *name, char **pipeline_desc) g_return_val_if_reached (-EINVAL); } - return 0; + return svcdb_pipeline_get (name, pipeline_desc); } /** @@ -52,7 +54,7 @@ ml_agent_pipeline_delete (const char *name) g_return_val_if_reached (-EINVAL); } - return 0; + return svcdb_pipeline_delete (name); } /** @@ -65,7 +67,7 @@ ml_agent_pipeline_launch (const char *name, int64_t * id) g_return_val_if_reached (-EINVAL); } - return 0; + return mlops_node_create (name, MLOPS_NODE_TYPE_PIPELINE, id); } /** @@ -74,7 +76,7 @@ ml_agent_pipeline_launch (const char *name, int64_t * id) int ml_agent_pipeline_start (const int64_t id) { - return 0; + return mlops_node_start (id); } /** @@ -83,7 +85,7 @@ ml_agent_pipeline_start (const int64_t id) int ml_agent_pipeline_stop (const int64_t id) { - return 0; + return mlops_node_stop (id); } /** @@ -92,7 +94,7 @@ ml_agent_pipeline_stop (const int64_t id) int ml_agent_pipeline_destroy (const int64_t id) { - return 0; + return mlops_node_destroy (id); } /** @@ -101,7 +103,7 @@ ml_agent_pipeline_destroy (const int64_t id) int ml_agent_pipeline_get_state (const int64_t id, int *state) { - return 0; + return mlops_node_get_state (id, (GstState *) state); } /** @@ -115,7 +117,8 @@ ml_agent_model_register (const char *name, const char *path, if (!STR_IS_VALID (name) || !STR_IS_VALID (path) || !version) { g_return_val_if_reached (-EINVAL); } - return 0; + + return svcdb_model_add (name, path, activate, description, app_info, version); } /** @@ -128,7 +131,8 @@ ml_agent_model_update_description (const char *name, if (!STR_IS_VALID (name) || !STR_IS_VALID (description) || version == 0U) { g_return_val_if_reached (-EINVAL); } - return 0; + + return svcdb_model_update_description (name, version, description); } /** @@ -141,7 +145,7 @@ ml_agent_model_activate (const char *name, const uint32_t version) g_return_val_if_reached (-EINVAL); } - return 0; + return svcdb_model_activate (name, version); } /** @@ -154,7 +158,7 @@ ml_agent_model_get (const char *name, const uint32_t version, char **model_info) g_return_val_if_reached (-EINVAL); } - return 0; + return svcdb_model_get (name, version, model_info); } /** @@ -167,7 +171,7 @@ ml_agent_model_get_activated (const char *name, char **model_info) g_return_val_if_reached (-EINVAL); } - return 0; + return svcdb_model_get_activated (name, model_info); } /** @@ -180,7 +184,7 @@ ml_agent_model_get_all (const char *name, char **model_info) g_return_val_if_reached (-EINVAL); } - return 0; + return svcdb_model_get_all (name, model_info); } /** @@ -195,7 +199,7 @@ ml_agent_model_delete (const char *name, const uint32_t version, g_return_val_if_reached (-EINVAL); } - return 0; + return svcdb_model_delete (name, version, force); } /** @@ -209,7 +213,7 @@ ml_agent_resource_add (const char *name, const char *path, g_return_val_if_reached (-EINVAL); } - return 0; + return svcdb_resource_add (name, path, description, app_info); } /** @@ -222,7 +226,7 @@ ml_agent_resource_delete (const char *name) g_return_val_if_reached (-EINVAL); } - return 0; + return svcdb_resource_delete (name); } /** @@ -235,5 +239,5 @@ ml_agent_resource_get (const char *name, char **res_info) g_return_val_if_reached (-EINVAL); } - return 0; + return svcdb_resource_get (name, res_info); } diff --git a/daemon/mlops-agent-interface.c b/daemon/mlops-agent-interface.c index d18a029..0193f4d 100644 --- a/daemon/mlops-agent-interface.c +++ b/daemon/mlops-agent-interface.c @@ -202,6 +202,7 @@ ml_agent_pipeline_set_description (const char *name, const char *pipeline_desc) { MachinelearningServicePipeline *mlsp; gboolean result; + gint ret; if (!STR_IS_VALID (name) || !STR_IS_VALID (pipeline_desc)) { g_return_val_if_reached (-EINVAL); @@ -213,10 +214,10 @@ ml_agent_pipeline_set_description (const char *name, const char *pipeline_desc) } result = machinelearning_service_pipeline_call_set_pipeline_sync (mlsp, - name, pipeline_desc, NULL, NULL, NULL); + name, pipeline_desc, &ret, NULL, NULL); g_object_unref (mlsp); - g_return_val_if_fail (result, -EIO); + g_return_val_if_fail (ret == 0 && result, ret); return 0; } diff --git a/daemon/mlops-agent-internal.c b/daemon/mlops-agent-internal.c new file mode 100755 index 0000000..b921a12 --- /dev/null +++ b/daemon/mlops-agent-internal.c @@ -0,0 +1,37 @@ +/* SPDX-License-Identifier: Apache-2.0 */ +/** + * @file mlops-agent-internal.c + * @date 20 January 2025 + * @brief Internal function for ml-agent interface. + * @see https://github.com/nnstreamer/deviceMLOps.MLAgent + * @author Jaeyun Jung + * @bug No known bugs except for NYI items + */ + +#include "log.h" +#include "mlops-agent-internal.h" +#include "mlops-agent-node.h" +#include "service-db-util.h" + +/** + * @brief Internal function to initialize mlops-agent interface. + */ +void +ml_agent_initialize (const char *db_path) +{ + g_assert (STR_IS_VALID (db_path)); + g_assert (g_file_test (db_path, G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR)); + + svcdb_initialize (db_path); + mlops_node_initialize (); +} + +/** + * @brief Internal function to finalize mlops-agent interface. + */ +void +ml_agent_finalize (void) +{ + mlops_node_finalize (); + svcdb_finalize (); +} diff --git a/daemon/mlops-agent-internal.h b/daemon/mlops-agent-internal.h index b2aead4..15c19fb 100755 --- a/daemon/mlops-agent-internal.h +++ b/daemon/mlops-agent-internal.h @@ -29,6 +29,16 @@ typedef enum ML_AGENT_SERVICE_END } ml_agent_service_type_e; +/** + * @brief Internal function to initialize mlops-agent interface. + */ +void ml_agent_initialize (const char *db_path); + +/** + * @brief Internal function to finalize mlops-agent interface. + */ +void ml_agent_finalize (void); + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/daemon/mlops-agent-node.c b/daemon/mlops-agent-node.c new file mode 100755 index 0000000..bbb901d --- /dev/null +++ b/daemon/mlops-agent-node.c @@ -0,0 +1,284 @@ +/* SPDX-License-Identifier: Apache-2.0 */ +/** + * NNStreamer API / Machine Learning Agent Daemon + * Copyright (C) 2025 Samsung Electronics Co., Ltd. All Rights Reserved. + */ + +/** + * @file mlops-agent-node.c + * @date 20 january 2025 + * @brief Implementation of mlops node. + * @see https://github.com/nnstreamer/deviceMLOps.MLAgent + * @author Jaeyun Jung + * @bug No known bugs except for NYI items + * @details This implements the node information to run a pipeline. + */ + +#include "log.h" +#include "mlops-agent-node.h" +#include "service-db-util.h" + +static GHashTable *g_mlops_node_table = NULL; +G_LOCK_DEFINE_STATIC (mlops_node_table); + +/** + * @brief Structure for mlops node. + */ +typedef struct +{ + mlops_node_type_e type; + gint64 id; + GMutex lock; + GstElement *element; + gchar *service_name; + gchar *description; +} mlops_node_s; + +/** + * @brief Internal function to get node info. + */ +static mlops_node_s * +_mlops_node_get (const int64_t id) +{ + mlops_node_s *node = NULL; + + G_LOCK (mlops_node_table); + node = (mlops_node_s *) g_hash_table_lookup (g_mlops_node_table, + GINT_TO_POINTER (id)); + G_UNLOCK (mlops_node_table); + + if (!node) { + ml_loge ("There is no pipeline matched with ID %" G_GINT64_FORMAT, id); + } + + return node; +} + +/** + * @brief Internal function to change pipeline state. + */ +static int +_mlops_node_set_pipeline_state (mlops_node_s * node, GstState state) +{ + GstStateChangeReturn ret; + + g_return_val_if_fail (node != NULL, -EINVAL); + + g_mutex_lock (&node->lock); + ret = gst_element_set_state (node->element, state); + g_mutex_unlock (&node->lock); + + if (ret == GST_STATE_CHANGE_FAILURE) { + ml_loge ("Failed to set the state of the pipeline to %s with ID %" + G_GINT64_FORMAT, gst_element_state_get_name (state), node->id); + return -ESTRPIPE; + } + + return 0; +} + +/** + * @brief Internal function to release mlops node. + */ +static void +_mlops_node_free (gpointer data) +{ + mlops_node_s *node = (mlops_node_s *) data; + + if (!node) { + ml_logw ("The data pointer is null, internal error?"); + return; + } + + _mlops_node_set_pipeline_state (node, GST_STATE_NULL); + + g_mutex_lock (&node->lock); + + node->type = MLOPS_NODE_TYPE_NONE; + node->id = 0; + if (node->element) { + gst_object_unref (node->element); + node->element = NULL; + } + g_free (node->service_name); + node->service_name = NULL; + g_free (node->description); + node->description = NULL; + + g_mutex_unlock (&node->lock); + + g_mutex_clear (&node->lock); + g_free (node); +} + +/** + * @brief Initialize mlops node info. + */ +void +mlops_node_initialize (void) +{ + G_LOCK (mlops_node_table); + if (!g_mlops_node_table) { + g_mlops_node_table = g_hash_table_new_full (g_direct_hash, g_direct_equal, + NULL, _mlops_node_free); + } + g_assert (g_mlops_node_table != NULL); + G_UNLOCK (mlops_node_table); +} + +/** + * @brief Finalize mlops node info. + */ +void +mlops_node_finalize (void) +{ + G_LOCK (mlops_node_table); + g_assert (g_mlops_node_table != NULL); + g_hash_table_destroy (g_mlops_node_table); + g_mlops_node_table = NULL; + G_UNLOCK (mlops_node_table); +} + +/** + * @brief Check service name and launch the pipeline. + */ +int +mlops_node_create (const gchar * name, const mlops_node_type_e type, + int64_t * id) +{ + mlops_node_s *node = NULL; + gint result = -EIO; + gchar *desc = NULL; + GstElement *pipeline = NULL; + GError *err = NULL; + GstStateChangeReturn ret; + + switch (type) { + case MLOPS_NODE_TYPE_PIPELINE: + { + result = svcdb_pipeline_get (name, &desc); + if (result != 0) { + ml_loge ("Failed to launch pipeline of '%s'.", name); + goto error; + } + break; + } + default: + return -EINVAL; + } + + pipeline = gst_parse_launch (desc, &err); + if (!pipeline || err) { + ml_loge ("Failed to launch pipeline '%s' (error msg: %s).", + desc, (err) ? err->message : "unknown reason"); + g_clear_error (&err); + + if (pipeline) + gst_object_unref (pipeline); + + result = -ESTRPIPE; + goto error; + } + + /* Set pipeline as paused state. */ + ret = gst_element_set_state (pipeline, GST_STATE_PAUSED); + if (ret == GST_STATE_CHANGE_FAILURE) { + ml_loge + ("Failed to set the state of the pipeline to PAUSED. For the detail, please check the GStreamer log message."); + + gst_object_unref (pipeline); + result = -ESTRPIPE; + goto error; + } + + /* Add node info into hash table. */ + node = g_new0 (mlops_node_s, 1); + node->type = type; + node->id = g_get_monotonic_time (); + node->element = pipeline; + node->service_name = g_strdup (name); + node->description = g_strdup (desc); + g_mutex_init (&node->lock); + + G_LOCK (mlops_node_table); + g_hash_table_insert (g_mlops_node_table, GINT_TO_POINTER (node->id), node); + G_UNLOCK (mlops_node_table); + +error: + if (result == 0) { + *id = node->id; + } else { + if (node) + _mlops_node_free (node); + } + + g_free (desc); + return result; +} + +/** + * @brief Start the pipeline with given id. + */ +int +mlops_node_start (const int64_t id) +{ + mlops_node_s *node = NULL; + + node = _mlops_node_get (id); + return _mlops_node_set_pipeline_state (node, GST_STATE_PLAYING); +} + +/** + * @brief Stop the pipeline with given id. + */ +int +mlops_node_stop (const int64_t id) +{ + mlops_node_s *node = NULL; + + node = _mlops_node_get (id); + return _mlops_node_set_pipeline_state (node, GST_STATE_PAUSED); +} + +/** + * @brief Destroy the pipeline with given id. + */ +int +mlops_node_destroy (const int64_t id) +{ + mlops_node_s *node = NULL; + + node = _mlops_node_get (id); + if (node) { + G_LOCK (mlops_node_table); + g_hash_table_remove (g_mlops_node_table, GINT_TO_POINTER (id)); + G_UNLOCK (mlops_node_table); + } + + return node ? 0 : -EINVAL; +} + +/** + * @brief Get the state of pipeline with given id. + */ +int +mlops_node_get_state (const int64_t id, GstState * state) +{ + mlops_node_s *node = NULL; + GstStateChangeReturn ret; + + node = _mlops_node_get (id); + g_return_val_if_fail (node != NULL, -EINVAL); + + g_mutex_lock (&node->lock); + ret = gst_element_get_state (node->element, state, NULL, GST_MSECOND); + g_mutex_unlock (&node->lock); + + if (ret == GST_STATE_CHANGE_FAILURE) { + ml_loge ("Failed to get the state of the pipeline with ID %" + G_GINT64_FORMAT, id); + return -ESTRPIPE; + } + + return 0; +} diff --git a/daemon/mlops-agent-node.h b/daemon/mlops-agent-node.h new file mode 100755 index 0000000..53d99e4 --- /dev/null +++ b/daemon/mlops-agent-node.h @@ -0,0 +1,71 @@ +/* SPDX-License-Identifier: Apache-2.0 */ +/** + * NNStreamer API / Machine Learning Agent Daemon + * Copyright (C) 2025 Samsung Electronics Co., Ltd. All Rights Reserved. + */ + +/** + * @file mlops-agent-node.h + * @date 20 january 2025 + * @brief Implementation of mlops node. + * @see https://github.com/nnstreamer/deviceMLOps.MLAgent + * @author Jaeyun Jung + * @bug No known bugs except for NYI items + * @details This implements the node information to run a pipeline. + */ + +#ifndef _MLOPS_AGENT_NODE_H_ +#define _MLOPS_AGENT_NODE_H_ + +#include +#include + +G_BEGIN_DECLS + +/** + * @brief Enumeration for mlops node type. + */ +typedef enum +{ + MLOPS_NODE_TYPE_NONE = 0, + MLOPS_NODE_TYPE_PIPELINE, + MLOPS_NODE_TYPE_MAX +} mlops_node_type_e; + +/** + * @brief Initialize mlops node info. + */ +void mlops_node_initialize (void); + +/** + * @brief Finalize mlops node info. + */ +void mlops_node_finalize (void); + +/** + * @brief Check service name and launch the pipeline. + */ +int mlops_node_create (const gchar *name, const mlops_node_type_e type, int64_t *id); + +/** + * @brief Start the pipeline with given id. + */ +int mlops_node_start (const int64_t id); + +/** + * @brief Stop the pipeline with given id. + */ +int mlops_node_stop (const int64_t id); + +/** + * @brief Destroy the pipeline with given id. + */ +int mlops_node_destroy (const int64_t id); + +/* + * @brief Get the state of pipeline with given id. + */ +int mlops_node_get_state (const int64_t id, GstState *state); + +G_END_DECLS +#endif /* _MLOPS_AGENT_NODE_H_ */ diff --git a/daemon/pipeline-dbus-impl.cc b/daemon/pipeline-dbus-impl.cc index 07642ec..6cb2f6a 100644 --- a/daemon/pipeline-dbus-impl.cc +++ b/daemon/pipeline-dbus-impl.cc @@ -24,49 +24,12 @@ #include "dbus-interface.h" #include "gdbus-util.h" #include "log.h" +#include "mlops-agent-node.h" #include "modules.h" #include "pipeline-dbus.h" #include "service-db-util.h" static MachinelearningServicePipeline *g_gdbus_instance = NULL; -static GHashTable *pipeline_table = NULL; -G_LOCK_DEFINE_STATIC (pipeline_table_lock); - -/** - * @brief Structure for pipeline. - */ -typedef struct _pipeline { - GstElement *element; - gint64 id; - GMutex lock; - gchar *service_name; - gchar *description; -} pipeline_s; - -/** - * @brief Internal function to destroy pipeline instances. - */ -static void -_pipeline_free (gpointer data) -{ - pipeline_s *p; - - if (!data) { - ml_loge ("internal error, the data should not be NULL"); - return; - } - - p = (pipeline_s *) data; - - if (p->element) - gst_object_unref (p->element); - - g_free (p->service_name); - g_free (p->description); - g_mutex_clear (&p->lock); - - g_free (p); -} /** * @brief Get the skeleton object of the DBus interface. @@ -141,55 +104,8 @@ dbus_cb_core_launch_pipeline (MachinelearningServicePipeline *obj, { gint result = 0; gint64 id = -1; - GError *err = NULL; - GstStateChangeReturn sc_ret; - GstElement *pipeline = NULL; - pipeline_s *p; - g_autofree gchar *desc = NULL; - - result = svcdb_pipeline_get (service_name, &desc); - if (result != 0) { - ml_loge ("Failed to launch pipeline of '%s'.", service_name); - goto error; - } - - pipeline = gst_parse_launch (desc, &err); - if (!pipeline || err) { - ml_loge ("Failed to launch pipeline '%s' (error msg: %s).", - desc, (err) ? err->message : "unknown reason"); - g_clear_error (&err); - if (pipeline) - gst_object_unref (pipeline); - - result = -ESTRPIPE; - goto error; - } - - /** now set pipeline as paused state */ - sc_ret = gst_element_set_state (pipeline, GST_STATE_PAUSED); - if (sc_ret == GST_STATE_CHANGE_FAILURE) { - ml_loge ("Failed to set the state of the pipeline to PAUSED. For the detail, please check the GStreamer log message. The input pipeline was '%s'.", - desc); - - gst_object_unref (pipeline); - result = -ESTRPIPE; - goto error; - } - - /** now fill the struct and store into hash table */ - p = g_new0 (pipeline_s, 1); - p->element = pipeline; - p->description = g_strdup (desc); - p->service_name = g_strdup (service_name); - g_mutex_init (&p->lock); - - G_LOCK (pipeline_table_lock); - id = p->id = g_get_monotonic_time (); - g_hash_table_insert (pipeline_table, GINT_TO_POINTER (p->id), p); - G_UNLOCK (pipeline_table_lock); - -error: + result = mlops_node_create (service_name, MLOPS_NODE_TYPE_PIPELINE, &id); machinelearning_service_pipeline_complete_launch_pipeline (obj, invoc, result, id); return TRUE; @@ -203,29 +119,8 @@ dbus_cb_core_start_pipeline (MachinelearningServicePipeline *obj, GDBusMethodInvocation *invoc, gint64 id, gpointer user_data) { gint result = 0; - GstStateChangeReturn sc_ret; - pipeline_s *p = NULL; - - G_LOCK (pipeline_table_lock); - p = (pipeline_s *) g_hash_table_lookup (pipeline_table, GINT_TO_POINTER (id)); - - if (!p) { - ml_loge ("The callback start_pipeline is called, but there is no pipeline matched with ID."); - G_UNLOCK (pipeline_table_lock); - result = -EINVAL; - } else { - g_mutex_lock (&p->lock); - G_UNLOCK (pipeline_table_lock); - sc_ret = gst_element_set_state (p->element, GST_STATE_PLAYING); - g_mutex_unlock (&p->lock); - - if (sc_ret == GST_STATE_CHANGE_FAILURE) { - ml_loge ("Failed to set the state of the pipeline to PLAYING whose service name is %s.", - p->service_name); - result = -ESTRPIPE; - } - } + result = mlops_node_start (id); machinelearning_service_pipeline_complete_start_pipeline (obj, invoc, result); return TRUE; @@ -239,29 +134,8 @@ dbus_cb_core_stop_pipeline (MachinelearningServicePipeline *obj, GDBusMethodInvocation *invoc, gint64 id, gpointer user_data) { gint result = 0; - GstStateChangeReturn sc_ret; - pipeline_s *p = NULL; - - G_LOCK (pipeline_table_lock); - p = (pipeline_s *) g_hash_table_lookup (pipeline_table, GINT_TO_POINTER (id)); - - if (!p) { - ml_loge ("The callback stop_pipeline is called, but there is no pipeline matched with ID."); - G_UNLOCK (pipeline_table_lock); - result = -EINVAL; - } else { - g_mutex_lock (&p->lock); - G_UNLOCK (pipeline_table_lock); - sc_ret = gst_element_set_state (p->element, GST_STATE_PAUSED); - g_mutex_unlock (&p->lock); - - if (sc_ret == GST_STATE_CHANGE_FAILURE) { - ml_loge ("Failed to set the state of the pipeline to PAUSED whose service name is %s.", - p->service_name); - result = -ESTRPIPE; - } - } + result = mlops_node_stop (id); machinelearning_service_pipeline_complete_stop_pipeline (obj, invoc, result); return TRUE; @@ -275,34 +149,8 @@ dbus_cb_core_destroy_pipeline (MachinelearningServicePipeline *obj, GDBusMethodInvocation *invoc, gint64 id, gpointer user_data) { gint result = 0; - pipeline_s *p = NULL; - - G_LOCK (pipeline_table_lock); - p = (pipeline_s *) g_hash_table_lookup (pipeline_table, GINT_TO_POINTER (id)); - - if (!p) { - ml_loge ("The callback destroy_pipeline is called, but there is no pipeline matched with ID."); - result = -EINVAL; - } else { - /** - * @todo Fix hanging issue when trying to set GST_STATE_NULL state for pipelines - * containing tensor_query_*. As a workaround, just unref the pipeline instance. - * To fix this issue, tensor_query elements and nnstreamer-edge should well-behavior - * to the state change. And it should properly free socket resources. Revive following code after then. - * - * GstStateChangeReturn sc_ret; - * g_mutex_lock (&p->lock); - * sc_ret = gst_element_set_state (p->element, GST_STATE_NULL); - * g_mutex_unlock (&p->lock); - * if (sc_ret == GST_STATE_CHANGE_FAILURE) { - * ml_loge ("Failed to set the state of the pipeline to NULL whose service name is %s. Destroy it anyway.", p->service_name); - * result = -ESTRPIPE; - * } - */ - g_hash_table_remove (pipeline_table, GINT_TO_POINTER (id)); - } - G_UNLOCK (pipeline_table_lock); + result = mlops_node_destroy (id); machinelearning_service_pipeline_complete_destroy_pipeline (obj, invoc, result); return TRUE; @@ -316,32 +164,9 @@ dbus_cb_core_get_state (MachinelearningServicePipeline *obj, GDBusMethodInvocation *invoc, gint64 id, gpointer user_data) { gint result = 0; - GstStateChangeReturn sc_ret; GstState state = GST_STATE_NULL; - pipeline_s *p = NULL; - - G_LOCK (pipeline_table_lock); - p = (pipeline_s *) g_hash_table_lookup (pipeline_table, GINT_TO_POINTER (id)); - - if (!p) { - ml_loge ("The callback get_state is called, but there is no pipeline matched with ID."); - result = -EINVAL; - machinelearning_service_pipeline_complete_get_state (obj, invoc, result, (gint) state); - G_UNLOCK (pipeline_table_lock); - return TRUE; - } - - g_mutex_lock (&p->lock); - G_UNLOCK (pipeline_table_lock); - sc_ret = gst_element_get_state (p->element, &state, NULL, GST_MSECOND); - g_mutex_unlock (&p->lock); - - if (sc_ret == GST_STATE_CHANGE_FAILURE) { - ml_loge ("Failed to get the state of the pipeline whose service name is %s.", - p->service_name); - result = -ESTRPIPE; - } + result = mlops_node_get_state (id, &state); machinelearning_service_pipeline_complete_get_state (obj, invoc, result, (gint) state); return TRUE; @@ -444,11 +269,6 @@ static void init_pipeline_module (void *data) { gdbus_initialize (); - - G_LOCK (pipeline_table_lock); - g_assert (NULL == pipeline_table); /** Internal error */ - pipeline_table = g_hash_table_new_full (g_direct_hash, g_direct_equal, NULL, _pipeline_free); - G_UNLOCK (pipeline_table_lock); } /** @@ -457,12 +277,6 @@ init_pipeline_module (void *data) static void exit_pipeline_module (void *data) { - G_LOCK (pipeline_table_lock); - g_assert (pipeline_table); /** Internal error */ - g_hash_table_destroy (pipeline_table); - pipeline_table = NULL; - G_UNLOCK (pipeline_table_lock); - gdbus_disconnect_signal (g_gdbus_instance, ARRAY_SIZE (handler_infos), handler_infos); gdbus_put_pipeline_instance (&g_gdbus_instance); } diff --git a/daemon/service-db-util.h b/daemon/service-db-util.h index 7565478..353dcaa 100644 --- a/daemon/service-db-util.h +++ b/daemon/service-db-util.h @@ -14,6 +14,7 @@ #define __SERVICE_DB_UTIL_H__ #include +#include G_BEGIN_DECLS diff --git a/jni/mlops-agent.mk b/jni/mlops-agent.mk index 706d573..188bcfd 100644 --- a/jni/mlops-agent.mk +++ b/jni/mlops-agent.mk @@ -6,4 +6,8 @@ endif MLOPS_AGENT_INCLUDE := $(MLOPS_AGENT_ROOT)/daemon/include # mlops agent sources -MLOPS_AGENT_SRCS := $(MLOPS_AGENT_ROOT)/daemon/mlops-agent-android.c +MLOPS_AGENT_SRCS := \ + $(MLOPS_AGENT_ROOT)/daemon/mlops-agent-android.c \ + $(MLOPS_AGENT_ROOT)/daemon/mlops-agent-internal.c \ + $(MLOPS_AGENT_ROOT)/daemon/mlops-agent-node.c \ + $(MLOPS_AGENT_ROOT)/daemon/service-db.cc