LCOV - code coverage report
Current view: top level - capi-machine-learning-inference-1.8.6/c/src - ml-api-service.c (source / functions) Coverage Total Hit
Test: ML API 1.8.6-0 platform/core/api/machine-learning#681b884c6a50f3134065311d1610991dcdde916e Lines: 0.0 % 354 0
Test Date: 2024-10-30 18:02:44 Functions: 0.0 % 19 0

            Line data    Source code
       1              : /* SPDX-License-Identifier: Apache-2.0 */
       2              : /**
       3              :  * Copyright (c) 2022 Samsung Electronics Co., Ltd. All Rights Reserved.
       4              :  *
       5              :  * @file ml-api-service.c
       6              :  * @date 31 Aug 2022
       7              :  * @brief Some implementation of NNStreamer/Service C-API
       8              :  * @see https://github.com/nnstreamer/nnstreamer
       9              :  * @author Yongjoo Ahn <yongjoo1.ahn@samsung.com>
      10              :  * @bug No known bugs except for NYI items
      11              :  */
      12              : 
      13              : #include <nnstreamer_plugin_api_util.h>
      14              : 
      15              : #include "ml-api-service.h"
      16              : #include "ml-api-service-extension.h"
      17              : #include "ml-api-service-offloading.h"
      18              : 
      19              : #define ML_SERVICE_MAGIC 0xfeeedeed
      20              : #define ML_SERVICE_MAGIC_DEAD 0xdeaddead
      21              : 
      22              : /**
      23              :  * @brief Internal function to validate ml-service handle.
      24              :  */
      25              : gboolean
      26            0 : _ml_service_handle_is_valid (ml_service_s * mls)
      27              : {
      28            0 :   if (!mls)
      29            0 :     return FALSE;
      30              : 
      31            0 :   if (mls->magic != ML_SERVICE_MAGIC)
      32            0 :     return FALSE;
      33              : 
      34            0 :   switch (mls->type) {
      35            0 :     case ML_SERVICE_TYPE_SERVER_PIPELINE:
      36              :     case ML_SERVICE_TYPE_CLIENT_QUERY:
      37              :     case ML_SERVICE_TYPE_OFFLOADING:
      38              :     case ML_SERVICE_TYPE_EXTENSION:
      39            0 :       if (mls->priv == NULL)
      40            0 :         return FALSE;
      41            0 :       break;
      42            0 :     default:
      43              :       /* Invalid handle type. */
      44            0 :       return FALSE;
      45              :   }
      46              : 
      47            0 :   return TRUE;
      48              : }
      49              : 
      50              : /**
      51              :  * @brief Internal function to set information.
      52              :  */
      53              : static int
      54            0 : _ml_service_set_information_internal (ml_service_s * mls, const char *name,
      55              :     const char *value)
      56              : {
      57            0 :   int status = ML_ERROR_NONE;
      58              : 
      59              :   /* Prevent empty string case. */
      60            0 :   if (!STR_IS_VALID (name) || !STR_IS_VALID (value))
      61            0 :     return ML_ERROR_INVALID_PARAMETER;
      62              : 
      63            0 :   status = ml_option_set (mls->information, name, g_strdup (value), g_free);
      64            0 :   if (status != ML_ERROR_NONE)
      65            0 :     return status;
      66              : 
      67            0 :   switch (mls->type) {
      68            0 :     case ML_SERVICE_TYPE_EXTENSION:
      69            0 :       status = _ml_service_extension_set_information (mls, name, value);
      70            0 :       break;
      71            0 :     case ML_SERVICE_TYPE_OFFLOADING:
      72            0 :       status = _ml_service_offloading_set_information (mls, name, value);
      73            0 :       break;
      74            0 :     default:
      75            0 :       break;
      76              :   }
      77              : 
      78            0 :   return status;
      79              : }
      80              : 
      81              : /**
      82              :  * @brief Internal function to create new ml-service handle.
      83              :  */
      84              : ml_service_s *
      85            0 : _ml_service_create_internal (ml_service_type_e ml_service_type)
      86              : {
      87              :   ml_service_s *mls;
      88              :   int status;
      89              : 
      90            0 :   mls = g_try_new0 (ml_service_s, 1);
      91            0 :   if (mls) {
      92            0 :     status = ml_option_create (&mls->information);
      93            0 :     if (status != ML_ERROR_NONE) {
      94            0 :       g_free (mls);
      95            0 :       _ml_error_report_return (NULL,
      96              :           "Failed to create ml-option handle in ml-service.");
      97              :     }
      98              : 
      99            0 :     mls->magic = ML_SERVICE_MAGIC;
     100            0 :     mls->type = ml_service_type;
     101            0 :     g_mutex_init (&mls->lock);
     102            0 :     g_cond_init (&mls->cond);
     103              :   }
     104              : 
     105            0 :   return mls;
     106              : }
     107              : 
     108              : /**
     109              :  * @brief Internal function to release ml-service handle.
     110              :  */
     111              : int
     112            0 : _ml_service_destroy_internal (ml_service_s * mls)
     113              : {
     114              :   ml_service_event_cb_info_s old_cb;
     115            0 :   int status = ML_ERROR_NONE;
     116              : 
     117            0 :   if (!mls) {
     118              :     /* Internal error? */
     119            0 :     return ML_ERROR_INVALID_PARAMETER;
     120              :   }
     121              : 
     122              :   /* Clear callback before closing internal handles. */
     123            0 :   g_mutex_lock (&mls->lock);
     124            0 :   old_cb = mls->cb_info;
     125            0 :   memset (&mls->cb_info, 0, sizeof (ml_service_event_cb_info_s));
     126            0 :   g_mutex_unlock (&mls->lock);
     127              : 
     128            0 :   switch (mls->type) {
     129            0 :     case ML_SERVICE_TYPE_SERVER_PIPELINE:
     130            0 :       status = _ml_service_pipeline_release_internal (mls);
     131            0 :       break;
     132            0 :     case ML_SERVICE_TYPE_CLIENT_QUERY:
     133            0 :       status = _ml_service_query_release_internal (mls);
     134            0 :       break;
     135            0 :     case ML_SERVICE_TYPE_OFFLOADING:
     136            0 :       status = _ml_service_offloading_release_internal (mls);
     137            0 :       break;
     138            0 :     case ML_SERVICE_TYPE_EXTENSION:
     139            0 :       status = _ml_service_extension_destroy (mls);
     140            0 :       break;
     141            0 :     default:
     142            0 :       _ml_error_report ("Invalid type of ml_service_h.");
     143            0 :       status = ML_ERROR_INVALID_PARAMETER;
     144            0 :       break;
     145              :   }
     146              : 
     147            0 :   if (status == ML_ERROR_NONE) {
     148            0 :     mls->magic = ML_SERVICE_MAGIC_DEAD;
     149            0 :     ml_option_destroy (mls->information);
     150              : 
     151            0 :     g_cond_clear (&mls->cond);
     152            0 :     g_mutex_clear (&mls->lock);
     153            0 :     g_free (mls);
     154              :   } else {
     155            0 :     _ml_error_report ("Failed to release ml-service handle, internal error?");
     156              : 
     157            0 :     g_mutex_lock (&mls->lock);
     158            0 :     mls->cb_info = old_cb;
     159            0 :     g_mutex_unlock (&mls->lock);
     160              :   }
     161              : 
     162            0 :   return status;
     163              : }
     164              : 
     165              : /**
     166              :  * @brief Internal function to get ml-service event callback.
     167              :  */
     168              : void
     169            0 : _ml_service_get_event_cb_info (ml_service_s * mls,
     170              :     ml_service_event_cb_info_s * cb_info)
     171              : {
     172            0 :   if (!mls || !cb_info)
     173            0 :     return;
     174              : 
     175            0 :   g_mutex_lock (&mls->lock);
     176            0 :   *cb_info = mls->cb_info;
     177            0 :   g_mutex_unlock (&mls->lock);
     178              : }
     179              : 
     180              : /**
     181              :  * @brief Internal function to parse string value from json.
     182              :  */
     183              : int
     184            0 : _ml_service_conf_parse_string (JsonNode * str_node, const gchar * delimiter,
     185              :     gchar ** str)
     186              : {
     187              :   guint i, n;
     188              : 
     189            0 :   if (!str_node || !delimiter || !str)
     190            0 :     return ML_ERROR_INVALID_PARAMETER;
     191              : 
     192            0 :   *str = NULL;
     193              : 
     194            0 :   if (JSON_NODE_HOLDS_ARRAY (str_node)) {
     195            0 :     JsonArray *array = json_node_get_array (str_node);
     196            0 :     GString *val = g_string_new (NULL);
     197              : 
     198            0 :     n = (array) ? json_array_get_length (array) : 0U;
     199            0 :     for (i = 0; i < n; i++) {
     200            0 :       const gchar *p = json_array_get_string_element (array, i);
     201              : 
     202              :       g_string_append (val, p);
     203            0 :       if (i < n - 1)
     204              :         g_string_append (val, delimiter);
     205              :     }
     206              : 
     207            0 :     *str = g_string_free (val, FALSE);
     208              :   } else {
     209            0 :     *str = g_strdup (json_node_get_string (str_node));
     210              :   }
     211              : 
     212            0 :   return (*str != NULL) ? ML_ERROR_NONE : ML_ERROR_INVALID_PARAMETER;
     213              : }
     214              : 
     215              : /**
     216              :  * @brief Internal function to parse tensors-info from json.
     217              :  */
     218              : int
     219            0 : _ml_service_conf_parse_tensors_info (JsonNode * info_node,
     220              :     ml_tensors_info_h * info_h)
     221              : {
     222            0 :   JsonArray *array = NULL;
     223              :   JsonObject *object;
     224              :   GstTensorsInfo info;
     225              :   GstTensorInfo *_info;
     226              :   const gchar *_str;
     227              :   guint i;
     228              :   int status;
     229              : 
     230            0 :   if (!info_node || !info_h)
     231            0 :     return ML_ERROR_INVALID_PARAMETER;
     232              : 
     233            0 :   gst_tensors_info_init (&info);
     234              : 
     235            0 :   info.num_tensors = 1;
     236            0 :   if (JSON_NODE_HOLDS_ARRAY (info_node)) {
     237            0 :     array = json_node_get_array (info_node);
     238            0 :     info.num_tensors = json_array_get_length (array);
     239              :   }
     240              : 
     241            0 :   for (i = 0; i < info.num_tensors; i++) {
     242            0 :     _info = gst_tensors_info_get_nth_info (&info, i);
     243              : 
     244            0 :     if (array)
     245            0 :       object = json_array_get_object_element (array, i);
     246              :     else
     247            0 :       object = json_node_get_object (info_node);
     248              : 
     249            0 :     if (json_object_has_member (object, "type")) {
     250            0 :       _str = json_object_get_string_member (object, "type");
     251              : 
     252            0 :       if (STR_IS_VALID (_str))
     253            0 :         _info->type = gst_tensor_get_type (_str);
     254              :     }
     255              : 
     256            0 :     if (json_object_has_member (object, "dimension")) {
     257            0 :       _str = json_object_get_string_member (object, "dimension");
     258              : 
     259            0 :       if (STR_IS_VALID (_str))
     260            0 :         gst_tensor_parse_dimension (_str, _info->dimension);
     261              :     }
     262              : 
     263            0 :     if (json_object_has_member (object, "name")) {
     264            0 :       _str = json_object_get_string_member (object, "name");
     265              : 
     266            0 :       if (STR_IS_VALID (_str))
     267            0 :         _info->name = g_strdup (_str);
     268              :     }
     269              :   }
     270              : 
     271            0 :   if (gst_tensors_info_validate (&info))
     272            0 :     status = _ml_tensors_info_create_from_gst (info_h, &info);
     273              :   else
     274            0 :     status = ML_ERROR_INVALID_PARAMETER;
     275              : 
     276            0 :   gst_tensors_info_free (&info);
     277            0 :   return status;
     278              : }
     279              : 
     280              : /**
     281              :  * @brief Internal function to get ml-service type.
     282              :  */
     283              : static ml_service_type_e
     284            0 : _ml_service_get_type (JsonObject * object)
     285              : {
     286            0 :   ml_service_type_e type = ML_SERVICE_TYPE_UNKNOWN;
     287              : 
     288              :   /** @todo add more services such as training offloading, offloading service */
     289            0 :   if (json_object_has_member (object, "single") ||
     290            0 :       json_object_has_member (object, "pipeline")) {
     291            0 :     type = ML_SERVICE_TYPE_EXTENSION;
     292            0 :   } else if (json_object_has_member (object, "offloading")) {
     293            0 :     type = ML_SERVICE_TYPE_OFFLOADING;
     294              :   }
     295              : 
     296            0 :   return type;
     297              : }
     298              : 
     299              : /**
     300              :  * @brief Creates a handle for machine learning service with configuration.
     301              :  */
     302              : int
     303            0 : ml_service_new (const char *config, ml_service_h * handle)
     304              : {
     305              :   ml_service_s *mls;
     306            0 :   ml_service_type_e service_type = ML_SERVICE_TYPE_UNKNOWN;
     307            0 :   g_autofree gchar *json_string = NULL;
     308            0 :   g_autoptr (JsonParser) parser = NULL;
     309            0 :   g_autoptr (GError) err = NULL;
     310              :   JsonNode *root;
     311              :   JsonObject *object;
     312              :   int status;
     313              : 
     314            0 :   check_feature_state (ML_FEATURE_SERVICE);
     315              : 
     316            0 :   if (!handle) {
     317            0 :     _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
     318              :         "The parameter, 'handle' (ml_service_h), is NULL. It should be a valid pointer to create new instance.");
     319              :   }
     320              : 
     321              :   /* Init null. */
     322            0 :   *handle = NULL;
     323              : 
     324            0 :   if (!STR_IS_VALID (config) ||
     325            0 :       !g_file_test (config, (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR))) {
     326            0 :     _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
     327              :         "The parameter, config, is invalid. It should be a valid path.");
     328              :   }
     329              : 
     330            0 :   if (!g_file_get_contents (config, &json_string, NULL, NULL)) {
     331            0 :     _ml_error_report_return (ML_ERROR_IO_ERROR,
     332              :         "Failed to read configuration file '%s'.", config);
     333              :   }
     334              : 
     335            0 :   parser = json_parser_new ();
     336            0 :   if (!parser) {
     337            0 :     _ml_error_report_return (ML_ERROR_OUT_OF_MEMORY,
     338              :         "Failed to parse configuration file, cannot allocate memory for JsonParser. Out of memory?");
     339              :   }
     340              : 
     341            0 :   if (!json_parser_load_from_data (parser, json_string, -1, &err)) {
     342            0 :     _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
     343              :         "Failed to parse configuration file. Parse error: %s",
     344              :         err ? err->message : "Unknown error");
     345              :   }
     346              : 
     347            0 :   root = json_parser_get_root (parser);
     348            0 :   if (!root) {
     349            0 :     _ml_error_report_return (ML_ERROR_IO_ERROR,
     350              :         "Failed to parse configuration file, cannot get the top node from json string.");
     351              :   }
     352              : 
     353            0 :   object = json_node_get_object (root);
     354              : 
     355            0 :   service_type = _ml_service_get_type (object);
     356            0 :   if (ML_SERVICE_TYPE_UNKNOWN == service_type) {
     357            0 :     _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
     358              :         "Failed to parse configuration file, cannot get the valid type from configuration.");
     359              :   }
     360              : 
     361              :   /* Parse each service type. */
     362            0 :   mls = _ml_service_create_internal (service_type);
     363            0 :   if (mls == NULL) {
     364            0 :     _ml_error_report_return (ML_ERROR_OUT_OF_MEMORY,
     365              :         "Failed to allocate memory for the ml-service handle. Out of memory?");
     366              :   }
     367              : 
     368            0 :   switch (service_type) {
     369            0 :     case ML_SERVICE_TYPE_EXTENSION:
     370            0 :       status = _ml_service_extension_create (mls, object);
     371            0 :       break;
     372            0 :     case ML_SERVICE_TYPE_OFFLOADING:
     373            0 :       status = _ml_service_offloading_create (mls, object);
     374            0 :       break;
     375            0 :     default:
     376              :       /* Invalid handle type. */
     377            0 :       status = ML_ERROR_NOT_SUPPORTED;
     378            0 :       break;
     379              :   }
     380              : 
     381            0 :   if (status != ML_ERROR_NONE)
     382            0 :     goto error;
     383              : 
     384              :   /* Parse information. */
     385            0 :   if (json_object_has_member (object, "information")) {
     386            0 :     JsonObject *info = json_object_get_object_member (object, "information");
     387            0 :     g_autoptr (GList) members = json_object_get_members (info);
     388              :     GList *iter;
     389              : 
     390            0 :     for (iter = members; iter; iter = g_list_next (iter)) {
     391            0 :       const gchar *name = iter->data;
     392            0 :       const gchar *value = _ml_service_get_json_string_member (info, name);
     393              : 
     394            0 :       status = _ml_service_set_information_internal (mls, name, value);
     395            0 :       if (status != ML_ERROR_NONE)
     396            0 :         goto error;
     397              :     }
     398              :   }
     399              : 
     400            0 : error:
     401            0 :   if (status == ML_ERROR_NONE) {
     402            0 :     *handle = mls;
     403              :   } else {
     404            0 :     _ml_error_report ("Failed to open the ml-service configuration.");
     405            0 :     _ml_service_destroy_internal (mls);
     406              :   }
     407              : 
     408            0 :   return status;
     409              : }
     410              : 
     411              : /**
     412              :  * @brief Sets the callbacks which will be invoked when a new event occurs from ml-service.
     413              :  */
     414              : int
     415            0 : ml_service_set_event_cb (ml_service_h handle, ml_service_event_cb cb,
     416              :     void *user_data)
     417              : {
     418            0 :   ml_service_s *mls = (ml_service_s *) handle;
     419              : 
     420            0 :   check_feature_state (ML_FEATURE_SERVICE);
     421              : 
     422            0 :   if (!_ml_service_handle_is_valid (mls)) {
     423            0 :     _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
     424              :         "The parameter, 'handle' (ml_service_h), is invalid. It should be a valid ml_service_h instance, which is usually created by ml_service_new().");
     425              :   }
     426              : 
     427            0 :   g_mutex_lock (&mls->lock);
     428              : 
     429            0 :   mls->cb_info.cb = cb;
     430            0 :   mls->cb_info.pdata = user_data;
     431              : 
     432            0 :   g_mutex_unlock (&mls->lock);
     433              : 
     434            0 :   return ML_ERROR_NONE;
     435              : }
     436              : 
     437              : /**
     438              :  * @brief Starts the process of ml-service.
     439              :  */
     440              : int
     441            0 : ml_service_start (ml_service_h handle)
     442              : {
     443            0 :   ml_service_s *mls = (ml_service_s *) handle;
     444            0 :   int status = ML_ERROR_NONE;
     445              : 
     446            0 :   check_feature_state (ML_FEATURE_SERVICE);
     447              : 
     448            0 :   if (!_ml_service_handle_is_valid (mls)) {
     449            0 :     _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
     450              :         "The parameter, 'handle' (ml_service_h), is invalid. It should be a valid ml_service_h instance, which is usually created by ml_service_new().");
     451              :   }
     452              : 
     453            0 :   switch (mls->type) {
     454            0 :     case ML_SERVICE_TYPE_SERVER_PIPELINE:
     455              :     {
     456            0 :       _ml_service_server_s *server = (_ml_service_server_s *) mls->priv;
     457              : 
     458            0 :       status = ml_agent_pipeline_start (server->id);
     459            0 :       if (status < 0)
     460            0 :         _ml_error_report ("Failed to invoke the method start_pipeline.");
     461              : 
     462            0 :       break;
     463              :     }
     464            0 :     case ML_SERVICE_TYPE_EXTENSION:
     465            0 :       status = _ml_service_extension_start (mls);
     466            0 :       break;
     467            0 :     case ML_SERVICE_TYPE_OFFLOADING:
     468            0 :       status = _ml_service_offloading_start (mls);
     469            0 :       break;
     470            0 :     default:
     471              :       /* Invalid handle type. */
     472            0 :       status = ML_ERROR_NOT_SUPPORTED;
     473            0 :       break;
     474              :   }
     475              : 
     476            0 :   return status;
     477              : }
     478              : 
     479              : /**
     480              :  * @brief Stops the process of ml-service.
     481              :  */
     482              : int
     483            0 : ml_service_stop (ml_service_h handle)
     484              : {
     485            0 :   ml_service_s *mls = (ml_service_s *) handle;
     486            0 :   int status = ML_ERROR_NONE;
     487              : 
     488            0 :   check_feature_state (ML_FEATURE_SERVICE);
     489              : 
     490            0 :   if (!_ml_service_handle_is_valid (mls)) {
     491            0 :     _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
     492              :         "The parameter, 'handle' (ml_service_h), is invalid. It should be a valid ml_service_h instance, which is usually created by ml_service_new().");
     493              :   }
     494              : 
     495            0 :   switch (mls->type) {
     496            0 :     case ML_SERVICE_TYPE_SERVER_PIPELINE:
     497              :     {
     498            0 :       _ml_service_server_s *server = (_ml_service_server_s *) mls->priv;
     499              : 
     500            0 :       status = ml_agent_pipeline_stop (server->id);
     501            0 :       if (status < 0)
     502            0 :         _ml_error_report ("Failed to invoke the method stop_pipeline.");
     503              : 
     504            0 :       break;
     505              :     }
     506            0 :     case ML_SERVICE_TYPE_EXTENSION:
     507            0 :       status = _ml_service_extension_stop (mls);
     508            0 :       break;
     509            0 :     case ML_SERVICE_TYPE_OFFLOADING:
     510            0 :       status = _ml_service_offloading_stop (mls);
     511            0 :       break;
     512            0 :     default:
     513              :       /* Invalid handle type. */
     514            0 :       status = ML_ERROR_NOT_SUPPORTED;
     515            0 :       break;
     516              :   }
     517              : 
     518            0 :   return status;
     519              : }
     520              : 
     521              : /**
     522              :  * @brief Gets the information of required input data.
     523              :  */
     524              : int
     525            0 : ml_service_get_input_information (ml_service_h handle, const char *name,
     526              :     ml_tensors_info_h * info)
     527              : {
     528            0 :   ml_service_s *mls = (ml_service_s *) handle;
     529              :   int status;
     530              : 
     531            0 :   check_feature_state (ML_FEATURE_SERVICE);
     532              : 
     533            0 :   if (!_ml_service_handle_is_valid (mls)) {
     534            0 :     _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
     535              :         "The parameter, 'handle' (ml_service_h), is invalid. It should be a valid ml_service_h instance, which is usually created by ml_service_new().");
     536              :   }
     537              : 
     538            0 :   if (!info) {
     539            0 :     _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
     540              :         "The parameter, info (ml_tensors_info_h), is NULL. It should be a valid pointer to create new instance.");
     541              :   }
     542              : 
     543              :   /* Init null. */
     544            0 :   *info = NULL;
     545              : 
     546            0 :   switch (mls->type) {
     547            0 :     case ML_SERVICE_TYPE_EXTENSION:
     548            0 :       status = _ml_service_extension_get_input_information (mls, name, info);
     549            0 :       break;
     550            0 :     default:
     551              :       /* Invalid handle type. */
     552            0 :       status = ML_ERROR_NOT_SUPPORTED;
     553            0 :       break;
     554              :   }
     555              : 
     556            0 :   if (status != ML_ERROR_NONE) {
     557            0 :     if (*info) {
     558            0 :       ml_tensors_info_destroy (*info);
     559            0 :       *info = NULL;
     560              :     }
     561              :   }
     562              : 
     563            0 :   return status;
     564              : }
     565              : 
     566              : /**
     567              :  * @brief Gets the information of output data.
     568              :  */
     569              : int
     570            0 : ml_service_get_output_information (ml_service_h handle, const char *name,
     571              :     ml_tensors_info_h * info)
     572              : {
     573            0 :   ml_service_s *mls = (ml_service_s *) handle;
     574              :   int status;
     575              : 
     576            0 :   check_feature_state (ML_FEATURE_SERVICE);
     577              : 
     578            0 :   if (!_ml_service_handle_is_valid (mls)) {
     579            0 :     _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
     580              :         "The parameter, 'handle' (ml_service_h), is invalid. It should be a valid ml_service_h instance, which is usually created by ml_service_new().");
     581              :   }
     582              : 
     583            0 :   if (!info) {
     584            0 :     _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
     585              :         "The parameter, info (ml_tensors_info_h), is NULL. It should be a valid pointer to create new instance.");
     586              :   }
     587              : 
     588              :   /* Init null. */
     589            0 :   *info = NULL;
     590              : 
     591            0 :   switch (mls->type) {
     592            0 :     case ML_SERVICE_TYPE_EXTENSION:
     593            0 :       status = _ml_service_extension_get_output_information (mls, name, info);
     594            0 :       break;
     595            0 :     default:
     596              :       /* Invalid handle type. */
     597            0 :       status = ML_ERROR_NOT_SUPPORTED;
     598            0 :       break;
     599              :   }
     600              : 
     601            0 :   if (status != ML_ERROR_NONE) {
     602            0 :     if (*info) {
     603            0 :       ml_tensors_info_destroy (*info);
     604            0 :       *info = NULL;
     605              :     }
     606              :   }
     607              : 
     608            0 :   return status;
     609              : }
     610              : 
     611              : /**
     612              :  * @brief Sets the information for ml-service.
     613              :  */
     614              : int
     615            0 : ml_service_set_information (ml_service_h handle, const char *name,
     616              :     const char *value)
     617              : {
     618            0 :   ml_service_s *mls = (ml_service_s *) handle;
     619              :   int status;
     620              : 
     621            0 :   check_feature_state (ML_FEATURE_SERVICE);
     622              : 
     623            0 :   if (!_ml_service_handle_is_valid (mls)) {
     624            0 :     _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
     625              :         "The parameter, 'handle' (ml_service_h), is invalid. It should be a valid ml_service_h instance, which is usually created by ml_service_new().");
     626              :   }
     627              : 
     628            0 :   if (!STR_IS_VALID (name)) {
     629            0 :     _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
     630              :         "The parameter, name '%s', is invalid.", name);
     631              :   }
     632              : 
     633            0 :   if (!STR_IS_VALID (value)) {
     634            0 :     _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
     635              :         "The parameter, value '%s', is invalid.", value);
     636              :   }
     637              : 
     638            0 :   g_mutex_lock (&mls->lock);
     639            0 :   status = _ml_service_set_information_internal (mls, name, value);
     640            0 :   g_mutex_unlock (&mls->lock);
     641              : 
     642            0 :   if (status != ML_ERROR_NONE) {
     643            0 :     _ml_error_report_return (status,
     644              :         "Failed to set the information '%s'.", name);
     645              :   }
     646              : 
     647            0 :   return ML_ERROR_NONE;
     648              : }
     649              : 
     650              : /**
     651              :  * @brief Gets the information from ml-service.
     652              :  */
     653              : int
     654            0 : ml_service_get_information (ml_service_h handle, const char *name, char **value)
     655              : {
     656            0 :   ml_service_s *mls = (ml_service_s *) handle;
     657            0 :   gchar *val = NULL;
     658              :   int status;
     659              : 
     660            0 :   check_feature_state (ML_FEATURE_SERVICE);
     661              : 
     662            0 :   if (!_ml_service_handle_is_valid (mls)) {
     663            0 :     _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
     664              :         "The parameter, 'handle' (ml_service_h), is invalid. It should be a valid ml_service_h instance, which is usually created by ml_service_new().");
     665              :   }
     666              : 
     667            0 :   if (!STR_IS_VALID (name)) {
     668            0 :     _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
     669              :         "The parameter, name '%s', is invalid.", name);
     670              :   }
     671              : 
     672            0 :   if (!value) {
     673            0 :     _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
     674              :         "The parameter, value, is NULL. It should be a valid pointer.");
     675              :   }
     676              : 
     677            0 :   g_mutex_lock (&mls->lock);
     678            0 :   status = ml_option_get (mls->information, name, (void **) (&val));
     679            0 :   g_mutex_unlock (&mls->lock);
     680              : 
     681            0 :   if (status != ML_ERROR_NONE) {
     682            0 :     _ml_error_report_return (status,
     683              :         "The ml-service handle does not include the information '%s'.", name);
     684              :   }
     685              : 
     686            0 :   *value = g_strdup (val);
     687            0 :   return ML_ERROR_NONE;
     688              : }
     689              : 
     690              : /**
     691              :  * @brief Adds an input data to process the model in ml-service extension handle.
     692              :  */
     693              : int
     694            0 : ml_service_request (ml_service_h handle, const char *name,
     695              :     const ml_tensors_data_h data)
     696              : {
     697            0 :   ml_service_s *mls = (ml_service_s *) handle;
     698              :   int status;
     699              : 
     700            0 :   check_feature_state (ML_FEATURE_SERVICE);
     701              : 
     702            0 :   if (!_ml_service_handle_is_valid (mls)) {
     703            0 :     _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
     704              :         "The parameter, 'handle' (ml_service_h), is invalid. It should be a valid ml_service_h instance, which is usually created by ml_service_new().");
     705              :   }
     706              : 
     707            0 :   if (!data) {
     708            0 :     _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
     709              :         "The parameter, data (ml_tensors_data_h), is NULL. It should be a valid ml_tensor_data_h instance, which is usually created by ml_tensors_data_create().");
     710              :   }
     711              : 
     712            0 :   switch (mls->type) {
     713            0 :     case ML_SERVICE_TYPE_EXTENSION:
     714            0 :       status = _ml_service_extension_request (mls, name, data);
     715            0 :       break;
     716            0 :     case ML_SERVICE_TYPE_OFFLOADING:
     717            0 :       status = _ml_service_offloading_request (mls, name, data);
     718            0 :       break;
     719            0 :     default:
     720              :       /* Invalid handle type. */
     721            0 :       status = ML_ERROR_NOT_SUPPORTED;
     722            0 :       break;
     723              :   }
     724              : 
     725            0 :   return status;
     726              : }
     727              : 
     728              : /**
     729              :  * @brief Destroys the handle for machine learning service.
     730              :  */
     731              : int
     732            0 : ml_service_destroy (ml_service_h handle)
     733              : {
     734            0 :   ml_service_s *mls = (ml_service_s *) handle;
     735              : 
     736            0 :   check_feature_state (ML_FEATURE_SERVICE);
     737              : 
     738            0 :   if (!_ml_service_handle_is_valid (mls)) {
     739            0 :     _ml_error_report_return (ML_ERROR_INVALID_PARAMETER,
     740              :         "The parameter, 'handle' (ml_service_h), is invalid. It should be a valid ml_service_h instance, which is usually created by ml_service_new().");
     741              :   }
     742              : 
     743            0 :   return _ml_service_destroy_internal (mls);
     744              : }
     745              : 
     746              : /**
     747              :  * @brief Internal function to get json string member.
     748              :  */
     749              : const gchar *
     750            0 : _ml_service_get_json_string_member (JsonObject * object,
     751              :     const gchar * member_name)
     752              : {
     753            0 :   const gchar *ret = NULL;
     754              : 
     755            0 :   if (!object) {
     756            0 :     _ml_error_report_return (ret,
     757              :         "The parameter, object (JsonObject *), is NULL. It should be a valid JsonObject instance.");
     758              :   }
     759              : 
     760            0 :   if (!member_name) {
     761            0 :     _ml_error_report_return (ret,
     762              :         "The parameter, member_name (const gchar *), is NULL.");
     763              :   }
     764              : 
     765            0 :   if (json_object_has_member (object, member_name)) {
     766            0 :     ret = json_object_get_string_member (object, member_name);
     767              :   }
     768              : 
     769            0 :   return ret;
     770              : }
        

Generated by: LCOV version 2.0-1