Add new api of stream and instance for multi-instance 68/219168/43 accepted/tizen/unified/20200309.215615 submit/tizen/20200309.062816
authorYoungHun Kim <yh8004.kim@samsung.com>
Tue, 3 Dec 2019 00:30:26 +0000 (09:30 +0900)
committerYoungHun Kim <yh8004.kim@samsung.com>
Wed, 4 Mar 2020 09:53:14 +0000 (18:53 +0900)
Change-Id: I5d940ac9704fec6f354d68f4a82d41c3c3f7956f

19 files changed:
packaging/mm-resource-manager.spec
packaging/org.tizen.MMResourceManager.xml
src/common/mm_resource_manager_utils.c
src/common/mm_resource_manager_utils.h
src/daemon/backend/mm_resource_manager_backend.c
src/daemon/backend/murphy/mm_resource_manager_backend.c
src/daemon/backend/murphy/mm_resource_manager_rset.c
src/daemon/mm_resource_manager_daemon.c
src/daemon/mm_resource_manager_daemon_conf.c
src/daemon/mm_resource_manager_daemon_conf.h
src/daemon/mm_resource_manager_daemon_dbus.c
src/daemon/mm_resource_manager_daemon_dbus.h
src/daemon/mm_resource_manager_daemon_priv.c
src/daemon/mm_resource_manager_daemon_priv.h
src/lib/mm_resource_manager.c
src/lib/mm_resource_manager.h
src/lib/mm_resource_manager_priv.c
src/lib/mm_resource_manager_priv.h
test/mm_res_manager_test.c

index 8231ee9..02ab0e9 100644 (file)
@@ -1,6 +1,6 @@
 Name:       mm-resource-manager
 Summary:    A Multimedia Resource Manager API
-Version:    0.2.19
+Version:    0.2.20
 Release:    0
 Group:      Multimedia/API
 License:    Apache-2.0
index 242bebf..1e583a2 100644 (file)
@@ -4,6 +4,7 @@
       <arg name="error" direction="out" type="i"/>
       <arg name="max_volume" direction="out" type="ai"/>
       <arg name="cond_volume" direction="out" type="aai"/>
+      <arg name="max_instance" direction="out" type="ai"/>
     </method>
     <method name="create">
       <arg name="app_class" direction="in" type="i"/>
index 93ef5d2..57c533b 100644 (file)
@@ -20,7 +20,7 @@
 
 
 
-static const charmm_resource_manager_res_str[MM_RESOURCE_MANAGER_RES_TYPE_MAX] = {
+static const char *mm_resource_manager_res_str[MM_RESOURCE_MANAGER_RES_TYPE_MAX] = {
        "video_decoder",
        "video_overlay",
        "camera",
@@ -29,34 +29,33 @@ static const char* mm_resource_manager_res_str[MM_RESOURCE_MANAGER_RES_TYPE_MAX]
        "audio_offload"
 };
 
-static const charmm_resource_manager_app_class_str[MM_RESOURCE_MANAGER_APP_CLASS_MAX] = {
+static const char *mm_resource_manager_app_class_str[MM_RESOURCE_MANAGER_APP_CLASS_MAX] = {
        "media",
        "interrupt"
 };
 
-static const charmm_resource_manager_condition_str[MM_RESOURCE_MANAGER_RES_TYPE_COND_MAX] = {
+static const char *mm_resource_manager_condition_str[MM_RESOURCE_MANAGER_RES_TYPE_COND_MAX] = {
        "SD",
        "HD",
        "FHD",
        "UHD"
 };
 
-
-const char* _mm_resource_manager_get_res_str(mm_resource_manager_res_type_e type)
+const char *_mm_resource_manager_get_res_str(mm_resource_manager_res_type_e type)
 {
        MM_RM_RETVM_IF(type < 0 || type >= MM_RESOURCE_MANAGER_RES_TYPE_MAX, "",
                        "Type is out of range");
        return mm_resource_manager_res_str[type];
 }
 
-const char_mm_resource_manager_get_app_class_str(mm_resource_manager_app_class_e cls)
+const char *_mm_resource_manager_get_app_class_str(mm_resource_manager_app_class_e cls)
 {
        MM_RM_RETVM_IF(cls < 0 || cls >= MM_RESOURCE_MANAGER_APP_CLASS_MAX, "",
                        "App class is out of range");
        return mm_resource_manager_app_class_str[cls];
 }
 
-const char_mm_resource_manager_get_condition_str(mm_resource_manager_res_type_cond_e cond)
+const char *_mm_resource_manager_get_condition_str(mm_resource_manager_res_type_cond_e cond)
 {
        MM_RM_RETVM_IF(cond < 0 || cond >= MM_RESOURCE_MANAGER_RES_TYPE_COND_MAX, "",
                        "Resource type condition is out of range");
index d1277df..8d7ca1c 100644 (file)
                var = var ^ (var >> 31);                                    \
        } while (0)
 
-#define MM_RESOURCE_MANAGER_NO_RES -2
-#define MM_RESOURCE_MANAGER_NO_APP_CLASS -1
-#define RELEASE_CB_SYNC_PATH "/tmp/.mm-res-mgr.fifo"
+#define MM_RESOURCE_MANAGER_NO_RES                     (-2)
+#define MM_RESOURCE_MANAGER_NO_APP_CLASS       (-1)
+#define RELEASE_CB_SYNC_PATH                           "/tmp/.mm-res-mgr.fifo"
 
 typedef uint64_t mm_resource_manager_id;
 
index a607d83..ac35b6d 100644 (file)
@@ -15,6 +15,7 @@
  */
 
 #include "daemon/backend/mm_resource_manager_backend.h"
+#include "daemon/mm_resource_manager_daemon_conf.h"
 #include "common/mm_resource_manager_utils.h"
 
 
@@ -33,8 +34,6 @@ int _mm_resource_manager_backend_deinit(void);
 int _mm_resource_manager_backend_acquire(mm_resource_manager_res_type_e type);
 int _mm_resource_manager_backend_release(mm_resource_manager_res_type_e type);
 
-
-
 static mm_resource_manager_backend_res_s resources[MM_RESOURCE_MANAGER_RES_TYPE_MAX];
 
 
@@ -70,6 +69,10 @@ int mm_resource_manager_backend_deinit(void)
 
 int mm_resource_manager_backend_acquire(mm_resource_manager_res_type_e type)
 {
+       MM_RM_RETVM_IF(type < MM_RESOURCE_MANAGER_RES_TYPE_VIDEO_DECODER ||
+                       type >= MM_RESOURCE_MANAGER_RES_TYPE_MAX,
+                       MM_RESOURCE_MANAGER_ERROR_INVALID_PARAMETER, "wrong type %d", type);
+
        resources[type].ref_counter++;
 
        return MM_RESOURCE_MANAGER_ERROR_NONE;
@@ -77,12 +80,16 @@ int mm_resource_manager_backend_acquire(mm_resource_manager_res_type_e type)
 
 int mm_resource_manager_backend_release(mm_resource_manager_res_type_e type)
 {
+       MM_RM_RETVM_IF(type < MM_RESOURCE_MANAGER_RES_TYPE_VIDEO_DECODER ||
+                       type >= MM_RESOURCE_MANAGER_RES_TYPE_MAX,
+                       MM_RESOURCE_MANAGER_ERROR_INVALID_PARAMETER, "wrong type %d", type);
+
        if (resources[type].ref_counter > 0) {
                resources[type].ref_counter--;
 
                return MM_RESOURCE_MANAGER_ERROR_NONE;
        } else {
-               MM_RM_ERROR("Reference counter is 0 already");
+               MM_RM_ERROR("Reference counter is already 0");
                return MM_RESOURCE_MANAGER_ERROR_INVALID_OPERATION;
        }
 }
@@ -119,16 +126,14 @@ int mm_resource_manager_backend_commit(mm_resource_manager_res_type_e type)
        return ret;
 }
 
-gboolean mm_resource_manager_backend_commit_all()
+gboolean mm_resource_manager_backend_commit_all(void)
 {
        int i;
        gboolean error = FALSE;
 
        for (i = 0; i < MM_RESOURCE_MANAGER_RES_TYPE_MAX; i++) {
-               if (mm_resource_manager_backend_commit(i) !=
-                               MM_RESOURCE_MANAGER_ERROR_NONE) {
+               if (mm_resource_manager_backend_commit(i) != MM_RESOURCE_MANAGER_ERROR_NONE)
                        error = TRUE;
-               }
        }
 
        return !error;
index d8fde6d..71d0f2b 100644 (file)
@@ -56,7 +56,7 @@ int _mm_resource_manager_backend_init(void)
        return MM_RESOURCE_MANAGER_ERROR_NONE;
 }
 
-int _mm_resource_manager_backend_deinit()
+int _mm_resource_manager_backend_deinit(void)
 {
        int ret;
 
@@ -83,6 +83,7 @@ int _mm_resource_manager_backend_acquire(mm_resource_manager_res_type_e type)
                MM_RM_ERROR("Failed to get is_run property from mloop");
                return ret;
        }
+
        if (!is_run) {
                MM_RM_ERROR("mloop is not ran");
                return MM_RESOURCE_MANAGER_ERROR_INVALID_STATE;
@@ -140,8 +141,6 @@ int _mm_resource_manager_backend_release(mm_resource_manager_res_type_e type)
        return MM_RESOURCE_MANAGER_ERROR_NONE;
 }
 
-
-
 static void __mm_resource_manager_mloop_error_cb(mm_resource_manager_mloop_s *mrp,
        mm_resource_manager_mloop_error_e err, void *user_data)
 {
@@ -166,13 +165,13 @@ static int __mm_resource_manager_add_resource(
        ret = _mm_resource_manager_rset_set_release_cb(rset[type],
                        __mm_resource_manager_release_cb, NULL);
        if (MM_RESOURCE_MANAGER_ERROR_NONE != ret) {
-               MM_RM_ERROR("Failed to set release callback to resource set %p", rset[type]);
+               MM_RM_ERROR("Failed to set release callback to resource set %p 0x%x", rset[type], ret);
                return ret;
        }
 
        ret = _mm_resource_manager_rset_add_resource(rset[type], type);
        if (MM_RESOURCE_MANAGER_ERROR_NONE != ret) {
-               MM_RM_ERROR("Failed to add resource to resource set");
+               MM_RM_ERROR("Failed to add resource to resource set 0x%x", ret);
                return ret;
        }
 
index 0e2d511..88278ed 100644 (file)
@@ -213,7 +213,7 @@ int _mm_resource_manager_rset_destroy(mm_resource_manager_rset_s *rset)
                                MM_RM_ERROR("Timeout elapsed");
                                ret = MM_RESOURCE_MANAGER_ERROR_INVALID_OPERATION;
                        } else {
-                               MM_RM_INFO("Released rset %p", rset);
+                               MM_RM_INFO("Released rset %p [%s]", rset, _mm_resource_manager_get_res_str(rset->type));
                                ret = MM_RESOURCE_MANAGER_ERROR_NONE;
                        }
                }
@@ -238,12 +238,9 @@ static void _mm_resource_manager_rset_release_cb(mrp_res_context_t *cx,
 {
        mm_resource_manager_rset_s *rset = NULL;
 
-       if (!user_data) {
-               MM_RM_ERROR("user data must be not NULL");
-               return;
-       }
+       MM_RM_RETM_IF(NULL == user_data, "user data must be not NULL");
 
-       rset =  (mm_resource_manager_rset_s *) user_data;
+       rset = (mm_resource_manager_rset_s *) user_data;
        MM_RM_INFO("Release callback was triggered for rset %p", rset);
 
        g_mutex_lock(&rset->lock);
@@ -268,7 +265,7 @@ static void _mm_resource_manager_rset_state_callback(mrp_res_context_t *cx, cons
                return;
        }
 
-       MM_RM_INFO(" - resource set state (%p) is changed to [%s]", rs, state_str[rs->state]);
+       MM_RM_INFO(" -- resource set state (%p) is changed to [%s]", rs, state_str[rs->state]);
        for (i = 0; i < MM_RESOURCE_MANAGER_RES_TYPE_MAX; i++) {
                res = mrp_res_get_resource_by_name(rs, _mm_resource_manager_get_res_str(i));
                if (res == NULL)
index ccedc8a..8153e07 100644 (file)
@@ -43,14 +43,14 @@ int notify_fd[2];
 static gboolean fork_wait(void);
 static daemonize_result_e daemonize(const char *path);
 static gboolean init_event(gpointer user_data);
-static void daemon_loop();
+static void daemon_loop(void);
 static gboolean remove_pid_file(void);
 static gboolean remove_ready_file(void);
 static gboolean remove_daemon_setup_file(void);
-static int set_signal_handlers();
+static int set_signal_handlers(void);
 static void terminate_handler(int signum);
 static void reload_conf_handler(int signum);
-static void quit_main_loop();
+static void quit_main_loop(void);
 
 
 
@@ -121,15 +121,14 @@ static gboolean init_event(gpointer user_data)
        return G_SOURCE_REMOVE;
 }
 
-static void daemon_loop()
+static void daemon_loop(void)
 {
        guint id = 0;
 
        do {
                restart = FALSE;
 
-               MM_RM_RETM_IF(!mm_resource_manager_reload_conf(),
-                               "Daemon cannot reload conf");
+               MM_RM_RETM_IF(!mm_resource_manager_reload_conf(), "Daemon cannot reload conf");
 
                main_loop = g_main_loop_new(NULL, FALSE);
                MM_RM_RETM_IF(main_loop == NULL, "Daemon cannot create main loop");
@@ -178,7 +177,7 @@ static gboolean remove_daemon_setup_file(void)
        return remove_pid_file() && remove_ready_file();
 }
 
-static int set_signal_handlers()
+static int set_signal_handlers(void)
 {
        struct sigaction sa_term;
        struct sigaction sa_reload_conf;
@@ -215,7 +214,7 @@ static void reload_conf_handler(int signum)
        quit_main_loop();
 }
 
-static void quit_main_loop()
+static void quit_main_loop(void)
 {
        if (main_loop) {
                _mmrm_dmn_status_callback(MM_RESOURCE_MANAGER_STATUS_DISCONNECTED);
index 7f7efc1..c650c83 100644 (file)
@@ -25,6 +25,7 @@
 #define MM_RESOURCE_MANAGER_INI_FILE "/etc/multimedia/mmfw_resource_manager.ini"
 #define MM_RESOURCE_MANAGER_INI_MAX_VOLUME "max volume:"
 #define MM_RESOURCE_MANAGER_INI_PRIORITY "priority:"
+#define MM_RESOURCE_MANAGER_INI_MAX_INSTANCE "max instance:"
 
 
 
@@ -35,59 +36,67 @@ static mm_resource_manager_conf_s mm_resource_manager_conf = {
                MM_RESOURCE_MANAGER_NO_APP_CLASS},
        {[0 ... MM_RESOURCE_MANAGER_RES_TYPE_MAX - 1]
         [0 ... MM_RESOURCE_MANAGER_RES_TYPE_COND_MAX - 1] =
+               MM_RESOURCE_MANAGER_NO_RES},
+       {[0 ... MM_RESOURCE_MANAGER_RES_TYPE_MAX - 1] =
                MM_RESOURCE_MANAGER_NO_RES}
 };
 
 
 
-gboolean mm_resource_manager_reload_conf()
+gboolean mm_resource_manager_reload_conf(void)
 {
        dictionary *ini;
        GString *param_name;
        int i, j;
 
        ini = iniparser_load(MM_RESOURCE_MANAGER_INI_FILE);
-       if (ini) {
-               param_name = g_string_sized_new(64);
-
-               for (i = 0; i < MM_RESOURCE_MANAGER_RES_TYPE_MAX; i++) {
-                       mm_resource_manager_conf.max_volume[i] = iniparser_getint(ini,
-                                       g_string_append(g_string_assign(param_name,
-                                       MM_RESOURCE_MANAGER_INI_MAX_VOLUME),
-                                       _mm_resource_manager_get_res_str(i))->str,
-                                       MM_RESOURCE_MANAGER_NO_RES);
-                       if (mm_resource_manager_conf.max_volume[i] >= 1) {
-                               for (j = 0; j < MM_RESOURCE_MANAGER_RES_TYPE_COND_MAX; j++) {
-                                       g_string_printf(param_name, "%s:%s",
-                                                       _mm_resource_manager_get_res_str(i),
-                                                       _mm_resource_manager_get_condition_str(j));
-                                       mm_resource_manager_conf.condition_volume[i][j] =
-                                                       iniparser_getint(ini, param_name->str,
-                                                       MM_RESOURCE_MANAGER_NO_RES);
-                               }
+       MM_RM_RETVM_IF(ini == NULL, FALSE,
+                       "Daemon cannot load conf file '%s'", MM_RESOURCE_MANAGER_INI_FILE);
+
+       param_name = g_string_sized_new(64);
+
+       for (i = 0; i < MM_RESOURCE_MANAGER_RES_TYPE_MAX; i++) {
+               mm_resource_manager_conf.max_volume[i] = iniparser_getint(ini,
+                               g_string_append(g_string_assign(param_name,
+                               MM_RESOURCE_MANAGER_INI_MAX_VOLUME),
+                               _mm_resource_manager_get_res_str(i))->str,
+                               MM_RESOURCE_MANAGER_NO_RES);
+               if (mm_resource_manager_conf.max_volume[i] >= 1) {
+                       mm_resource_manager_conf.volume_would_be_checked[i] = TRUE;
+                       for (j = 0; j < MM_RESOURCE_MANAGER_RES_TYPE_COND_MAX; j++) {
+                               g_string_printf(param_name, "%s:%s",
+                                               _mm_resource_manager_get_res_str(i),
+                                               _mm_resource_manager_get_condition_str(j));
+                               mm_resource_manager_conf.condition_volume[i][j] =
+                                               iniparser_getint(ini, param_name->str,
+                                               MM_RESOURCE_MANAGER_NO_RES);
                        }
                }
+       }
 
-               for (i = 0; i < MM_RESOURCE_MANAGER_APP_CLASS_MAX; i++) {
-                       mm_resource_manager_conf.priority[i] = iniparser_getint(ini,
-                                       g_string_append(g_string_assign(param_name,
-                                       MM_RESOURCE_MANAGER_INI_PRIORITY),
-                                       _mm_resource_manager_get_app_class_str(i))->str,
-                                       MM_RESOURCE_MANAGER_NO_APP_CLASS);
-               }
-
-               g_string_free(param_name, TRUE);
-               iniparser_freedict(ini);
+       for (i = 0; i < MM_RESOURCE_MANAGER_APP_CLASS_MAX; i++) {
+               mm_resource_manager_conf.priority[i] = iniparser_getint(ini,
+                               g_string_append(g_string_assign(param_name,
+                               MM_RESOURCE_MANAGER_INI_PRIORITY),
+                               _mm_resource_manager_get_app_class_str(i))->str,
+                               MM_RESOURCE_MANAGER_NO_APP_CLASS);
+       }
 
-               return TRUE;
-       } else {
-               MM_RM_ERROR("Daemon cannot load conf file '%s'",
-                               MM_RESOURCE_MANAGER_INI_FILE);
-               return FALSE;
+       for (i = 0; i < MM_RESOURCE_MANAGER_RES_TYPE_MAX; i++) {
+               mm_resource_manager_conf.max_instance[i] = iniparser_getint(ini,
+                                g_string_append(g_string_assign(param_name,
+                                MM_RESOURCE_MANAGER_INI_MAX_INSTANCE),
+                               _mm_resource_manager_get_res_str(i))->str,
+                                MM_RESOURCE_MANAGER_NO_RES);
        }
+
+       g_string_free(param_name, TRUE);
+       iniparser_freedict(ini);
+
+       return TRUE;
 }
 
-mm_resource_manager_conf_s* mm_resource_manager_get_conf()
+mm_resource_manager_conf_s* mm_resource_manager_get_conf(void)
 {
        return &mm_resource_manager_conf;
 }
index b5a31d4..d926cb0 100644 (file)
@@ -30,9 +30,11 @@ typedef struct {
        mm_resource_manager_res_volume max_volume[MM_RESOURCE_MANAGER_RES_TYPE_MAX];
        mm_resource_manager_priority priority[MM_RESOURCE_MANAGER_APP_CLASS_MAX];
        mm_resource_manager_condition_volume_a condition_volume;
+       int max_instance[MM_RESOURCE_MANAGER_RES_TYPE_MAX];
+       gboolean volume_would_be_checked[MM_RESOURCE_MANAGER_RES_TYPE_MAX];
 } mm_resource_manager_conf_s;
 
-gboolean mm_resource_manager_reload_conf();
-mm_resource_manager_conf_s* mm_resource_manager_get_conf();
+gboolean mm_resource_manager_reload_conf(void);
+mm_resource_manager_conf_s* mm_resource_manager_get_conf(void);
 
 #endif /* __MM_RESOURCE_MANAGER_DAEMON_CONF__ */
index 232465a..cd238a9 100755 (executable)
@@ -108,7 +108,7 @@ static gboolean _create_daemon_setup_file(void)
        return _create_pid_file() && _create_ready_file();
 }
 
-int _mmrm_dmn_dbus_init()
+int _mmrm_dmn_dbus_init(void)
 {
        interface = mmresource_manager_skeleton_new();
        MM_RM_RETVM_IF(interface == NULL,
@@ -120,7 +120,7 @@ int _mmrm_dmn_dbus_init()
        return MM_RESOURCE_MANAGER_ERROR_NONE;
 }
 
-int _mmrm_dmn_dbus_deinit()
+int _mmrm_dmn_dbus_deinit(void)
 {
        MM_RM_RETVM_IF(interface == NULL,
                        MM_RESOURCE_MANAGER_ERROR_INVALID_OPERATION, "Interface is NULL");
@@ -130,7 +130,7 @@ int _mmrm_dmn_dbus_deinit()
 }
 
 int _mmrm_dmn_dbus_get_conf(mm_resource_manager_res_volume **max_volume,
-               mm_resource_manager_condition_volume_a **cond_volume)
+               mm_resource_manager_condition_volume_a **cond_volume, int **max_instance)
 {
        mm_resource_manager_conf_s *conf;
 
@@ -142,6 +142,7 @@ int _mmrm_dmn_dbus_get_conf(mm_resource_manager_res_volume **max_volume,
 
        *max_volume = conf->max_volume;
        *cond_volume = &conf->condition_volume;
+       *max_instance = conf->max_instance;
 
        return MM_RESOURCE_MANAGER_ERROR_NONE;
 }
@@ -158,28 +159,29 @@ int _mmrm_dmn_dbus_destroy(mm_resource_manager_id id)
 }
 
 int _mmrm_dmn_dbus_commit(mm_resource_manager_id id, GVariantIter *release,
-               GVariantIter *acquire, gboolean **priority_error)
+               GVariantIter *acquire, gboolean **is_acquired)
 {
        int i;
        int ret;
        mm_resource_manager_dmn_res_request_s *release_requests = NULL,
                        *acquire_requests = NULL;
 
-       MM_RM_DEBUG("Commit release request of %"G_GSIZE_FORMAT" items",
-                       g_variant_iter_n_children(release));
        __gv2c_array(release, &release_requests);
+       if (release_requests->type != MM_RESOURCE_MANAGER_NO_RES)
+               MM_RM_DEBUG("Commit release request of %"G_GSIZE_FORMAT" items [type %d]",
+                       g_variant_iter_n_children(release), release_requests->type);
 
-       MM_RM_DEBUG("Commit acquire request of %"G_GSIZE_FORMAT" items",
-                       g_variant_iter_n_children(acquire));
        __gv2c_array(acquire, &acquire_requests);
+       if (acquire_requests->type != MM_RESOURCE_MANAGER_NO_RES)
+               MM_RM_DEBUG("Commit acquire request of %"G_GSIZE_FORMAT" items [type %d]",
+                       g_variant_iter_n_children(acquire), acquire_requests->type);
 
-       *priority_error = (gboolean *) g_malloc0_n(
-                       g_variant_iter_n_children(acquire), sizeof(**priority_error));
+       *is_acquired = (gboolean *) g_malloc0_n(g_variant_iter_n_children(acquire), sizeof(**is_acquired));
 
        ret = _mmrm_dmn_commit(id, release_requests, acquire_requests);
 
        for (i = 0; acquire_requests[i].type != MM_RESOURCE_MANAGER_NO_RES; i++)
-               (*priority_error)[i] = acquire_requests[i].priority_error;
+               (*is_acquired)[i] = acquire_requests[i].priority_error;
 
        g_free(release_requests);
        g_free(acquire_requests);
@@ -220,8 +222,10 @@ static void __gv2c_array(GVariantIter *gv, mm_resource_manager_dmn_res_request_s
 
        rs = (mm_resource_manager_dmn_res_request_s *)
                        g_malloc0_n(g_variant_iter_n_children(gv), sizeof(*rs));
-       for (i = 0; g_variant_iter_next(gv, "(ii)", &rs[i].type, &rs[i].volume); i++)
-               MM_RM_DEBUG("(type,vol) = (%d,%d)", rs[i].type, rs[i].volume);
+       for (i = 0; g_variant_iter_next(gv, "(ii)", &rs[i].type, &rs[i].volume); i++) {
+               if (rs[i].type != MM_RESOURCE_MANAGER_NO_RES)
+                       MM_RM_DEBUG("(type, vol) = (%d, %d)", rs[i].type, rs[i].volume);
+       }
 
        *c = rs;
 }
@@ -233,12 +237,15 @@ static gboolean on_get_conf(MMResourceManager *interface,
        gint error = 0;
        mm_resource_manager_res_volume *max_volume = NULL;
        mm_resource_manager_condition_volume_a *cond_volume = NULL;
+       int *max_instance = NULL;
        GVariantBuilder *res_type_builder;
        GVariantBuilder *res_cond_builder;
+       GVariantBuilder *res_instance_builder;
        GVariant *res_type_conf;
        GVariant *res_cond_conf;
+       GVariant *res_instance_conf;
 
-       error = _mmrm_dmn_dbus_get_conf(&max_volume, &cond_volume);
+       error = _mmrm_dmn_dbus_get_conf(&max_volume, &cond_volume, &max_instance);
 
        res_type_builder = g_variant_builder_new(G_VARIANT_TYPE_ARRAY);
        for (i = 0; i < MM_RESOURCE_MANAGER_RES_TYPE_MAX; i++)
@@ -259,7 +266,13 @@ static gboolean on_get_conf(MMResourceManager *interface,
        res_cond_conf = g_variant_builder_end(res_type_builder);
        g_variant_builder_unref(res_type_builder);
 
-       mmresource_manager_complete_conf(interface, invocation, error, res_type_conf, res_cond_conf);
+       res_instance_builder = g_variant_builder_new(G_VARIANT_TYPE_ARRAY);
+       for (i = 0; i < MM_RESOURCE_MANAGER_RES_TYPE_MAX; i++)
+               g_variant_builder_add_value(res_instance_builder, g_variant_new("i", max_instance[i]));
+       res_instance_conf = g_variant_builder_end(res_instance_builder);
+       g_variant_builder_unref(res_instance_builder);
+
+       mmresource_manager_complete_conf(interface, invocation, error, res_type_conf, res_cond_conf, res_instance_conf);
 
        return TRUE;
 }
@@ -330,7 +343,7 @@ static gboolean on_commit_handle(MMResourceManager *interface,
 static void on_bus_acquired(GDBusConnection *connection, const gchar *name,
                gpointer user_data)
 {
-       GErrorerror = NULL;
+       GError *error = NULL;
        MM_RM_DEBUG("name of bus = %s, userID = %d", name, getuid());
 
        g_signal_connect(interface, "handle-conf", G_CALLBACK(on_get_conf), NULL);
index aceaf82..e890be1 100644 (file)
@@ -27,7 +27,7 @@ int _mmrm_dmn_dbus_init(void);
 int _mmrm_dmn_dbus_deinit(void);
 void _mmrm_dmn_notify_fork_done(void);
 int _mmrm_dmn_dbus_get_conf(mm_resource_manager_res_volume **max_volume,
-               mm_resource_manager_condition_volume_a **cond_volume);
+               mm_resource_manager_condition_volume_a **cond_volume, int **max_instance);
 int _mmrm_dmn_dbus_create(mm_resource_manager_app_class_e app_class,
                mm_resource_manager_id *id);
 int _mmrm_dmn_dbus_destroy(mm_resource_manager_id id);
index a0bb41b..c866dc2 100644 (file)
@@ -48,7 +48,9 @@ typedef mm_resource_manager_dmn_res_s *mm_resource_manager_dmn_res_p;
 typedef struct {
        mm_resource_manager_id id;
        mm_resource_manager_app_class_e app_class;
-
+       mm_resource_manager_res_type_e type;
+       int volume;
+       gboolean is_released;
        /* if an element is NULL, there is no such a resource for the current platform. */
        mm_resource_manager_dmn_res_p resources[MM_RESOURCE_MANAGER_RES_TYPE_MAX];
 
@@ -63,8 +65,8 @@ typedef struct {
 
 
 
-static GPtrArray *managers = NULL;
-
+static GPtrArray *managers;
+static int res_count[MM_RESOURCE_MANAGER_RES_TYPE_MAX];
 
 
 static void __destroy_resource(mm_resource_manager_dmn_res_p res);
@@ -74,7 +76,7 @@ static inline mm_resource_manager_dmn_p __search_manager(mm_resource_manager_id
 static mm_resource_manager_error_e __check_release_requests(
                mm_resource_manager_dmn_p manager,
                mm_resource_manager_dmn_res_request_s *requests);
-static mm_resource_manager_dmn_res_request_s__create_increase_requests(
+static mm_resource_manager_dmn_res_request_s *__create_increase_requests(
                mm_resource_manager_dmn_res_request_s *releases,
                mm_resource_manager_dmn_res_request_s *acquires);
 static mm_resource_manager_error_e __check_increase_requests(
@@ -88,10 +90,8 @@ static void __handle_release_requests(mm_resource_manager_dmn_p manager,
 static GArray* __handle_acquire_requests(mm_resource_manager_dmn_p manager,
                mm_resource_manager_dmn_res_request_s *requests);
 static void __handle_release_callbacks(GArray *requests);
-static inline void __add_cb_request(GArray *cb_requests,
-               mm_resource_manager_dmn_p man,
-               mm_resource_manager_res_type_e type,
-               mm_resource_manager_res_volume volume);
+static inline void __add_cb_request(GArray *cb_requests, mm_resource_manager_dmn_p man,
+               mm_resource_manager_res_type_e type, mm_resource_manager_res_volume volume);
 static void __release_all_resources(mm_resource_manager_dmn_s *manager);
 static gboolean __wait_for_release_cb_sync(mm_resource_manager_id id);
 
@@ -134,7 +134,7 @@ gboolean _mmrm_dmn_deinit()
 
        if (managers) {
                for (i = 0; i < managers->len; i++)
-                       __release_all_resources((mm_resource_manager_dmn_s*)managers->pdata[i]);
+                       __release_all_resources((mm_resource_manager_dmn_p)managers->pdata[i]);
 
                mm_resource_manager_backend_commit_all();
                g_ptr_array_free(managers, TRUE);
@@ -174,6 +174,8 @@ mm_resource_manager_error_e _mmrm_dmn_create(
 
        g_ptr_array_add(managers, man);
 
+       MM_RM_INFO("managers length %d", managers->len);
+
        *id = man->id;
 
        return MM_RESOURCE_MANAGER_ERROR_NONE;
@@ -181,16 +183,25 @@ mm_resource_manager_error_e _mmrm_dmn_create(
 
 mm_resource_manager_error_e _mmrm_dmn_destroy(mm_resource_manager_id id)
 {
-       int i_man = __search_manager_index(id);
+       int idx = __search_manager_index(id);
+       mm_resource_manager_conf_s *conf = mm_resource_manager_get_conf();
+       mm_resource_manager_res_type_e type = MM_RESOURCE_MANAGER_RES_TYPE_MAX;
+       mm_resource_manager_dmn_p i_man = __search_manager(id);
 
-       MM_RM_RETVM_IF(i_man == MM_RESOURCE_MANGER_NOT_FOUND,
-                       MM_RESOURCE_MANAGER_ERROR_INVALID_PARAMETER,
+       MM_RM_RETVM_IF(idx == MM_RESOURCE_MANGER_NOT_FOUND, MM_RESOURCE_MANAGER_ERROR_INVALID_PARAMETER,
                        "Resource manager #%"PRIu64" doesn't exist", _mm_rm_hash64(id));
+       MM_RM_RETVM_IF(conf == NULL, MM_RESOURCE_MANAGER_ERROR_NONE, "conf is null");
 
-       __release_all_resources((mm_resource_manager_dmn_s*)managers->pdata[i_man]);
+       i_man = (mm_resource_manager_dmn_p)managers->pdata[idx];
+
+       __release_all_resources((mm_resource_manager_dmn_s *)managers->pdata[idx]);
        mm_resource_manager_backend_commit_all();
 
-       g_ptr_array_remove_index_fast(managers, i_man);
+       g_ptr_array_remove_index_fast(managers, idx);
+
+       type = i_man->type;
+
+       MM_RM_INFO("managers length #%d type %d available volume %d", managers->len, type, conf->max_volume[type]);
 
        return MM_RESOURCE_MANAGER_ERROR_NONE;
 }
@@ -208,8 +219,8 @@ mm_resource_manager_error_e _mmrm_dmn_commit(mm_resource_manager_id id,
                        MM_RESOURCE_MANAGER_ERROR_INVALID_PARAMETER,
                        "Resource manager #%"PRIu64" doesn't exist", _mm_rm_hash64(id));
        MM_RM_RETVM_IF(
-                       (releases == NULL || releases[0].type == MM_RESOURCE_MANAGER_NO_RES) &&
-                       (acquires == NULL || acquires[0].type == MM_RESOURCE_MANAGER_NO_RES),
+                       (releases == NULL || releases[0].type == MM_RESOURCE_MANAGER_NO_RES)
+                       && (acquires == NULL || acquires[0].type == MM_RESOURCE_MANAGER_NO_RES),
                        MM_RESOURCE_MANAGER_ERROR_INVALID_PARAMETER,
                        "Commit request is empty");
 
@@ -230,6 +241,8 @@ mm_resource_manager_error_e _mmrm_dmn_commit(mm_resource_manager_id id,
 
        __handle_release_requests(manager, releases);
        cb_requests = __handle_acquire_requests(manager, acquires);
+       MM_RM_RETVM_IF(cb_requests == NULL, MM_RESOURCE_MANAGER_ERROR_NOT_ENOUGH,
+                       "not enough free resource volume");
        __handle_release_callbacks(cb_requests);
        if (!mm_resource_manager_backend_commit_all()) {
                /*
@@ -254,8 +267,6 @@ void _mmrm_dmn_status_callback(mm_resource_manager_status_e status)
        _mmrm_dmn_dbus_status_callback(status);
 }
 
-
-
 static void __destroy_resource(mm_resource_manager_dmn_res_p res)
 {
        if (res == NULL)
@@ -284,9 +295,10 @@ static int __search_manager_index(mm_resource_manager_id id)
 {
        int i;
 
-       for (i = managers->len - 1; i >= 0; i--)
+       for (i = managers->len - 1; i >= 0; i--) {
                if (((mm_resource_manager_dmn_p)managers->pdata[i])->id == id)
                        return i;
+       }
 
        return MM_RESOURCE_MANGER_NOT_FOUND;
 }
@@ -297,41 +309,36 @@ static inline mm_resource_manager_dmn_p __search_manager(mm_resource_manager_id
        return i == MM_RESOURCE_MANGER_NOT_FOUND ? NULL : managers->pdata[i];
 }
 
-static mm_resource_manager_error_e __check_release_requests(
-               mm_resource_manager_dmn_p manager,
-               mm_resource_manager_dmn_res_request_s *requests)
+static mm_resource_manager_error_e __check_release_requests(mm_resource_manager_dmn_p manager,
+                       mm_resource_manager_dmn_res_request_s *requests)
 {
-       mm_resource_manager_dmn_res_request_p request;
        int i;
+       mm_resource_manager_conf_s *conf = mm_resource_manager_get_conf();
+       mm_resource_manager_res_type_e type = MM_RESOURCE_MANAGER_RES_TYPE_MAX;
 
-       if (requests == NULL)
-               return MM_RESOURCE_MANAGER_ERROR_NONE;
+       MM_RM_RETVM_IF(conf == NULL, MM_RESOURCE_MANAGER_ERROR_NONE, "conf is null");
+       MM_RM_RETVM_IF(requests == NULL, MM_RESOURCE_MANAGER_ERROR_NONE, "requests is null");
 
        for (; requests->type != MM_RESOURCE_MANAGER_NO_RES; requests++) {
 
-               request = requests;
-               const char *type_s = _mm_resource_manager_get_res_str(request->type);
+               type = requests->type;
+               const char *type_s = _mm_resource_manager_get_res_str(type);
 
-               MM_RM_RETVM_IF(manager->resources[request->type] == NULL,
-                               MM_RESOURCE_MANAGER_ERROR_NOT_SUPPORTED,
-                               "There is no resource %s for the platform", type_s);
+               MM_RM_RETVM_IF(manager->resources[type] == NULL,
+                       MM_RESOURCE_MANAGER_ERROR_NOT_SUPPORTED, "There is no resource %s for the platform", type_s);
 
-               if (manager->resources[request->type]->is_acquired) {
-                       if (manager->resources[request->type]->parts == NULL) {
-                               if (request->volume != MM_RESOURCE_MANAGER_RES_VOLUME_FULL) {
-                                       MM_RM_ERROR("Resource %s is acquired fully,"
-                                                       "but a resource part is tried to be released",
-                                                       type_s);
+               if (manager->resources[type]->is_acquired) {
+                       if (manager->resources[type]->parts == NULL) {
+                               if (requests->volume != MM_RESOURCE_MANAGER_RES_VOLUME_FULL) {
+                                       MM_RM_ERROR("Resource %s is acquired fully, but a resource part is tried to be released", type_s);
                                        return MM_RESOURCE_MANAGER_ERROR_INVALID_PARAMETER;
                                }
                        } else {
-                               for (i = 0; i < manager->resources[request->type]->parts->len &&
-                                               ((mm_resource_manager_res_volume*)
-                                               manager->resources[request->type]->parts->data)[i] !=
-                                               request->volume; i++);
-                               if (i == manager->resources[request->type]->parts->len) {
-                                       MM_RM_ERROR("Part of %s of volume %d is not acquired",
-                                                       type_s, request->volume);
+                               for (i = 0; i < manager->resources[type]->parts->len
+                                       && ((mm_resource_manager_res_volume*)manager->resources[type]->parts->data)[i]
+                                               != requests->volume; i++);
+                               if (i == manager->resources[type]->parts->len) {
+                                       MM_RM_ERROR("Part of %s of volume %d is not acquired", type_s, requests->volume);
                                        return MM_RESOURCE_MANAGER_ERROR_INVALID_PARAMETER;
                                }
                        }
@@ -339,62 +346,59 @@ static mm_resource_manager_error_e __check_release_requests(
                        MM_RM_ERROR("Resource %s is not acquired", type_s);
                        return MM_RESOURCE_MANAGER_ERROR_INVALID_PARAMETER;
                }
+               MM_RM_DEBUG("Release requests are OK type %d available volume %d", type, conf->max_volume[type]);
        }
 
-       MM_RM_DEBUG("Release requests are OK");
-
        return MM_RESOURCE_MANAGER_ERROR_NONE;
 }
 
-static mm_resource_manager_dmn_res_request_s* __create_increase_requests(
-               mm_resource_manager_dmn_res_request_s *releases,
-               mm_resource_manager_dmn_res_request_s *acquires)
+static mm_resource_manager_dmn_res_request_s *__create_increase_requests(
+               mm_resource_manager_dmn_res_request_s *releases, mm_resource_manager_dmn_res_request_s *acquires)
 {
        int i;
        int result_len = 1;
-       mm_resource_manager_dmn_res_request_s* result = NULL;
-       mm_resource_manager_dmn_res_request_s* result_iter = NULL;
-       mm_resource_manager_res_volume resources[MM_RESOURCE_MANAGER_RES_TYPE_MAX] = {0};
        mm_resource_manager_conf_s *conf = mm_resource_manager_get_conf();
+       mm_resource_manager_dmn_res_request_s *result = NULL;
+       mm_resource_manager_dmn_res_request_s *result_iter = NULL;
+       mm_resource_manager_res_volume resources[MM_RESOURCE_MANAGER_RES_TYPE_MAX] = { 0 };
+
+       MM_RM_RETVM_IF(conf == NULL, MM_RESOURCE_MANAGER_ERROR_NONE, "conf is null");
 
        for (; acquires->type != MM_RESOURCE_MANAGER_NO_RES; acquires++) {
 
-               if ((resources[acquires->type] > 0 || resources[acquires->type] ==
-                               MM_RESOURCE_MANAGER_RES_VOLUME_FULL) && acquires->volume ==
-                               MM_RESOURCE_MANAGER_RES_VOLUME_FULL) {
+               if ((resources[acquires->type] > 0 || resources[acquires->type] == MM_RESOURCE_MANAGER_RES_VOLUME_FULL)
+                       && acquires->volume == MM_RESOURCE_MANAGER_RES_VOLUME_FULL) {
                        MM_RM_ERROR("The client tries to acquire %s by part and fully at once",
                                        _mm_resource_manager_get_res_str(acquires->type));
                        return NULL;
                }
 
-               if (acquires->volume == MM_RESOURCE_MANAGER_RES_VOLUME_FULL)
+               if (acquires->volume == MM_RESOURCE_MANAGER_RES_VOLUME_FULL) {
                        resources[acquires->type] = MM_RESOURCE_MANAGER_RES_VOLUME_FULL;
-               else
-                       resources[acquires->type] += acquires->volume;
-
-               if (resources[acquires->type] > conf->max_volume[acquires->type]) {
-                       MM_RM_ERROR(
-                                       "The client tries to acquire %d units over max volume of %s",
-                                       resources[acquires->type] - conf->max_volume[acquires->type],
-                                       _mm_resource_manager_get_res_str(acquires->type));
-                       return NULL;
+               } else {
+                       if (conf->max_volume[acquires->type] > 1)
+                               resources[acquires->type] += acquires->volume;
+                       else
+                               resources[acquires->type]++;
                }
+
+               MM_RM_DEBUG("(type, vol) = (%d, %d)", acquires->type, resources[acquires->type]);
        }
 
-       for (; releases->type != MM_RESOURCE_MANAGER_NO_RES; releases++)
-               if (resources[releases->type] != MM_RESOURCE_MANAGER_RES_VOLUME_FULL)
-                       resources[releases->type] -= releases->volume;
+       for (; releases->type != MM_RESOURCE_MANAGER_NO_RES; releases++) {
+               if (resources[releases->type] > 1) {
+                       resources[releases->type] += releases->volume;
+                       MM_RM_INFO("type %d available volume %d", releases->type, resources[releases->type]);
+               }
+       }
 
        for (i = 0; i < MM_RESOURCE_MANAGER_RES_TYPE_MAX; i++)
-               if (resources[i] > 0 ||
-                               resources[i] == MM_RESOURCE_MANAGER_RES_VOLUME_FULL)
+               if (resources[i] > 0 || resources[i] == MM_RESOURCE_MANAGER_RES_VOLUME_FULL)
                        result_len++;
 
-       result_iter = result = g_new0(mm_resource_manager_dmn_res_request_s,
-                       result_len);
+       result_iter = result = g_new0(mm_resource_manager_dmn_res_request_s, result_len);
        for (i = 0; i < MM_RESOURCE_MANAGER_RES_TYPE_MAX; i++) {
-               if (resources[i] > 0 ||
-                               resources[i] == MM_RESOURCE_MANAGER_RES_VOLUME_FULL) {
+               if (resources[i] > 0 || resources[i] == MM_RESOURCE_MANAGER_RES_VOLUME_FULL) {
                        result_iter->type = i;
                        result_iter->volume = resources[i];
                        result_iter++;
@@ -405,65 +409,63 @@ static mm_resource_manager_dmn_res_request_s* __create_increase_requests(
        return result;
 }
 
-static mm_resource_manager_error_e __check_increase_requests(
-               mm_resource_manager_dmn_p manager,
-               mm_resource_manager_dmn_res_request_s *requests)
+static mm_resource_manager_error_e __check_increase_requests(mm_resource_manager_dmn_p manager,
+                       mm_resource_manager_dmn_res_request_s *requests)
 {
-       mm_resource_manager_dmn_res_request_p request;
        mm_resource_manager_res_volume remaining_volume;
        mm_resource_manager_dmn_p i_man;
        mm_resource_manager_conf_s *conf = mm_resource_manager_get_conf();
        gboolean resource_conflict = FALSE;
-       int i, j;
-
-       if (requests == NULL)
-               return MM_RESOURCE_MANAGER_ERROR_NONE;
+       int i, j, len;
+       mm_resource_manager_res_type_e type = MM_RESOURCE_MANAGER_RES_TYPE_MAX;
 
-       for (; requests->type != MM_RESOURCE_MANAGER_NO_RES; requests++) {
+       MM_RM_RETVM_IF(conf == NULL, MM_RESOURCE_MANAGER_ERROR_NONE, "conf is null");
+       MM_RM_RETVM_IF(requests == NULL, MM_RESOURCE_MANAGER_ERROR_NONE, "requests is null");
 
-               request = requests;
-               const char *type_s = _mm_resource_manager_get_res_str(request->type);
+       len = managers->len;
 
-               MM_RM_RETVM_IF(manager->resources[request->type] == NULL,
+       for (; requests->type != MM_RESOURCE_MANAGER_NO_RES; requests++) {
+               type = requests->type;
+               const char *type_s = _mm_resource_manager_get_res_str(type);
+
+               MM_RM_RETVM_IF(type < MM_RESOURCE_MANAGER_RES_TYPE_VIDEO_DECODER
+                               || type >= MM_RESOURCE_MANAGER_RES_TYPE_MAX,
+                               MM_RESOURCE_MANAGER_ERROR_INVALID_PARAMETER,
+                               "wrong type %d", type);
+               MM_RM_RETVM_IF(manager->resources[type] == NULL,
                                MM_RESOURCE_MANAGER_ERROR_NOT_SUPPORTED,
                                "There is no resource %s for the platform", type_s);
 
-               remaining_volume = conf->max_volume[request->type];
-               for (i = 0; i < managers->len; i++) {
-                       i_man = (mm_resource_manager_dmn_p)managers->pdata[i];
-                       if (i_man != manager && conf->priority[i_man->app_class] >
-                                       conf->priority[manager->app_class] &&
-                                       i_man->resources[request->type]->is_acquired) {
+               remaining_volume = conf->max_volume[type];
 
-                               if (i_man->resources[request->type]->parts) {
-                                       if (request->volume == MM_RESOURCE_MANAGER_RES_VOLUME_FULL) {
+               for (i = 0; i < len; i++) {
+                       i_man = (mm_resource_manager_dmn_p)managers->pdata[i];
 
-                                               request->priority_error = TRUE;
+                       if (i_man != manager && conf->priority[i_man->app_class] > conf->priority[manager->app_class]
+                               && i_man->resources[type]->is_acquired) {
+                               if (i_man->resources[type]->parts) {
+                                       if (requests->volume == MM_RESOURCE_MANAGER_RES_VOLUME_FULL) {
+                                               requests->priority_error = TRUE;
                                                resource_conflict = TRUE;
-                                               MM_RM_DEBUG("Resource conflict. Full volume is "
-                                                               "requested, but only part is available");
+                                               MM_RM_DEBUG("Resource conflict. Full volume is requested, but only part is available");
                                                break;
                                        } else {
-                                               for (j = 0; j < i_man->resources[request->type]->parts->len; j++)
-                                                       remaining_volume -= g_array_index(
-                                                                       i_man->resources[request->type]->parts,
-                                                                       mm_resource_manager_res_volume, j);
+                                               for (j = 0; j < i_man->resources[type]->parts->len; j++)
+                                                       remaining_volume -= g_array_index(i_man->resources[type]->parts,
+                                                                                               mm_resource_manager_res_volume, j);
 
-                                               if (remaining_volume < request->volume) {
-                                                       request->priority_error = TRUE;
+                                               if (remaining_volume < requests->volume) {
+                                                       requests->priority_error = TRUE;
                                                        resource_conflict = TRUE;
-                                                       MM_RM_DEBUG("Resource conflict. %d of %s are "
-                                                               "available, but %d required", remaining_volume,
-                                                               type_s, request->volume);
+                                                       MM_RM_DEBUG("Resource conflict. %d of %s are available, but %d required",
+                                                                       remaining_volume, type_s, requests->volume);
                                                        break;
                                                }
                                        }
                                } else {
-
-                                       request->priority_error = TRUE;
+                                       requests->priority_error = TRUE;
                                        resource_conflict = TRUE;
-                                       MM_RM_DEBUG("Resource conflict. %s is already "
-                                                       "acquired fully", type_s);
+                                       MM_RM_DEBUG("Resource conflict. %s is already acquired fully", type_s);
                                        break;
                                }
                        }
@@ -474,203 +476,191 @@ static mm_resource_manager_error_e __check_increase_requests(
                MM_RM_DEBUG("There is resource conflict");
                return MM_RESOURCE_MANAGER_ERROR_LOW_PRIORITY;
        } else {
-               MM_RM_DEBUG("Increase requests are OK");
+               MM_RM_DEBUG("type %d", type);
                return MM_RESOURCE_MANAGER_ERROR_NONE;
        }
 }
 
-static void __sync_increase_acquire_requests(
-               mm_resource_manager_dmn_res_request_s *increases,
-               mm_resource_manager_dmn_res_request_s *acquires)
+static void __sync_increase_acquire_requests(mm_resource_manager_dmn_res_request_s *increases,
+                       mm_resource_manager_dmn_res_request_s *acquires)
 {
        mm_resource_manager_dmn_res_request_s *increase_iter;
        mm_resource_manager_dmn_res_request_s *acquire_iter;
 
-       for (increase_iter = increases;
-                       increase_iter->type != MM_RESOURCE_MANAGER_NO_RES;
-                       increase_iter++)
-               for (acquire_iter = acquires;
-                               acquire_iter->type != MM_RESOURCE_MANAGER_NO_RES;
-                               acquire_iter++)
+       for (increase_iter = increases; increase_iter->type != MM_RESOURCE_MANAGER_NO_RES; increase_iter++) {
+               for (acquire_iter = acquires; acquire_iter->type != MM_RESOURCE_MANAGER_NO_RES; acquire_iter++) {
                        if (acquire_iter->type == increase_iter->type)
                                acquire_iter->priority_error = increase_iter->priority_error;
+               }
+       }
 }
 
-static inline void __add_cb_request(GArray *cb_requests,
-               mm_resource_manager_dmn_p man,
-               mm_resource_manager_res_type_e type,
-               mm_resource_manager_res_volume volume)
+static inline void __add_cb_request(GArray *cb_requests,mm_resource_manager_dmn_p man,
+                       mm_resource_manager_res_type_e type, mm_resource_manager_res_volume volume)
 {
        mm_resource_manager_dmn_release_cb_request_s *cb_request;
 
        g_array_set_size(cb_requests, cb_requests->len + 1);
-       cb_request = &g_array_index(cb_requests,
-                       mm_resource_manager_dmn_release_cb_request_s, cb_requests->len - 1);
+       cb_request = &g_array_index(cb_requests, mm_resource_manager_dmn_release_cb_request_s, cb_requests->len - 1);
 
        cb_request->manager = man;
        cb_request->type = type;
        cb_request->volume = volume;
 }
 
-static GArray__handle_acquire_requests(mm_resource_manager_dmn_p manager,
+static GArray *__handle_acquire_requests(mm_resource_manager_dmn_p manager,
                mm_resource_manager_dmn_res_request_s *requests)
 {
        mm_resource_manager_conf_s *conf = mm_resource_manager_get_conf();
-       mm_resource_manager_dmn_res_request_p request;
-       mm_resource_manager_res_volume acquired_volume;
-       mm_resource_manager_dmn_p i_man;
-
+       mm_resource_manager_res_volume acquired_volume = 0;
+       mm_resource_manager_dmn_p i_man = NULL, j_man = NULL;
+       const char *res_name = NULL;
        GArray *cb_requests = NULL;
-       GArray *parts;
-       gboolean is_released_fully;
-       gboolean enough_volume;
-       int i, j;
+       GArray *res = NULL;
+       int i =0, j = 0;
+       gboolean is_released_called_once = FALSE;
+       mm_resource_manager_res_type_e type = MM_RESOURCE_MANAGER_RES_TYPE_MAX;
+       mm_resource_manager_res_volume volume = MM_RESOURCE_MANAGER_RES_VOLUME_FULL;
 
-       if (requests == NULL)
-               return NULL;
+       MM_RM_RETVM_IF(conf == NULL, NULL, "conf is NULL");
+       MM_RM_RETVM_IF(requests == NULL, NULL, "requests is NULL");
 
-       cb_requests = g_array_sized_new(FALSE, FALSE,
-                       sizeof(mm_resource_manager_dmn_release_cb_request_s),
+       cb_requests = g_array_sized_new(FALSE, FALSE, sizeof(mm_resource_manager_dmn_release_cb_request_s),
                        MM_RESOURCE_MANAGER_RESERVED_CALLBACK_ARRAY_SIZE);
 
        for (; requests->type != MM_RESOURCE_MANAGER_NO_RES; requests++) {
+               type = requests->type;
+               res_name = _mm_resource_manager_get_res_str(type);
+               volume = requests->volume;
 
-               request = requests;
-               const char *res_name = _mm_resource_manager_get_res_str(request->type);
-
-               if (request->volume == MM_RESOURCE_MANAGER_RES_VOLUME_FULL) {
+               if (volume == MM_RESOURCE_MANAGER_RES_VOLUME_FULL) {
                        MM_RM_DEBUG("Full volume of %s is requested", res_name);
 
                        for (i = 0; i < managers->len; i++) {
                                i_man = (mm_resource_manager_dmn_p)managers->pdata[i];
 
-                               if (!i_man->resources[request->type]->is_acquired ||
-                                               conf->priority[i_man->app_class] >
-                                               conf->priority[manager->app_class])
+                               if (!i_man->resources[type]->is_acquired
+                                       ||conf->priority[i_man->app_class] >conf->priority[manager->app_class]) {
+                                       i_man->resources[type]->is_acquired = TRUE;
+                                       if (conf->max_instance[type] > 0)
+                                               res_count[type]++;
                                        continue;
+                               }
+
+                               res = i_man->resources[type]->parts;
+                               if (res) {
 
-                               parts = i_man->resources[request->type]->parts;
-                               if (parts) {
-                                       for (j = 0; j < parts->len; j++) {
-                                               __add_cb_request(cb_requests, i_man, request->type,
-                                                               g_array_index(parts,
-                                                               mm_resource_manager_res_volume, j));
+                                       for (j = 0; j < res->len; j++) {
+                                               __add_cb_request(cb_requests, i_man, type,
+                                                               g_array_index(res, mm_resource_manager_res_volume, j));
 
-                                               mm_resource_manager_backend_release(request->type);
+                                               mm_resource_manager_backend_release(type);
                                        }
 
-                                       g_array_free(parts, TRUE);
-                                       i_man->resources[request->type]->parts = NULL;
-                                       i_man->resources[request->type]->is_acquired = FALSE;
+                                       g_array_free(res, TRUE);
+                                       i_man->resources[type]->parts = NULL;
+                                       i_man->resources[type]->is_acquired = FALSE;
 
                                        MM_RM_DEBUG("All parts of %s are released in RM %"PRIu64,
                                                        res_name, _mm_rm_hash64(i_man->id));
                                } else {
-                                       __add_cb_request(cb_requests, i_man, request->type,
-                                                       MM_RESOURCE_MANAGER_RES_VOLUME_FULL);
+                                       __add_cb_request(cb_requests, i_man, type, MM_RESOURCE_MANAGER_RES_VOLUME_FULL);
 
-                                       mm_resource_manager_backend_release(request->type);
+                                       mm_resource_manager_backend_release(type);
 
-                                       i_man->resources[request->type]->is_acquired = FALSE;
+                                       i_man->resources[type]->is_acquired = FALSE;
 
-                                       MM_RM_DEBUG("Full resource %s is released in RM %"PRIu64,
-                                                       res_name, _mm_rm_hash64(i_man->id));
+                                       MM_RM_DEBUG("Full resource %s is released in RM %"PRIu64" available volume %d",
+                                               res_name, _mm_rm_hash64(i_man->id), conf->max_volume[type]);
                                        break;
                                }
                        }
                } else {
-                       MM_RM_DEBUG("%d units of %s are requested", request->volume,
-                                       res_name);
+                       MM_RM_INFO("[managers len #%d] [%d type #%d (max #%d)] [%d (max %d) units of %s] are requested",
+                               managers->len, type, res_count[type] + 1,
+                               conf->max_instance[type], volume, conf->max_volume[type], res_name);
 
-                       acquired_volume = 0;
-                       is_released_fully = FALSE;
                        for (i = 0; i < managers->len; i++) {
                                i_man = (mm_resource_manager_dmn_p)managers->pdata[i];
+                               res = i_man->resources[type]->parts;
 
-                               if (!i_man->resources[request->type]->is_acquired ||
-                                               conf->priority[i_man->app_class] >
-                                               conf->priority[manager->app_class])
-                                       continue;
+                               if (!i_man->resources[type]->is_acquired || res
+                                       || conf->priority[i_man->app_class] > conf->priority[manager->app_class]) {
 
-                               parts = i_man->resources[request->type]->parts;
-                               if (parts) {
-                                       for (j = 0; j < parts->len; j++) {
-                                               acquired_volume += g_array_index(parts,
-                                                               mm_resource_manager_res_volume, j);
+                                       if (conf->volume_would_be_checked[type] && conf->max_volume[type] >= 0 && !res) {
+                                               conf->max_volume[type] -= volume;
+                                               MM_RM_INFO("[type %d] - %d = %d", type, volume, conf->max_volume[type]);
                                        }
-                               } else {
-                                       __add_cb_request(cb_requests, i_man, request->type,
-                                                       MM_RESOURCE_MANAGER_RES_VOLUME_FULL);
 
-                                       mm_resource_manager_backend_release(request->type);
+                                       if (conf->max_instance[type] > 0 && conf->max_instance[type] == res_count[type]
+                                               && !is_released_called_once) {
+                                               for (j = 0; j < managers->len; j++) {
+                                                       j_man = (mm_resource_manager_dmn_p)managers->pdata[j];
+                                                       res = j_man->resources[type]->parts;
 
-                                       i_man->resources[request->type]->is_acquired = FALSE;
-                                       is_released_fully = TRUE;
+                                                       if (res && !j_man->is_released) {
+                                                               MM_RM_INFO("[#%d] [#%d / #%d] would be released %s in RM %"PRIu64,
+                                                               managers->len, j + 1, res->len, res_name, _mm_rm_hash64(j_man->id));
 
-                                       MM_RM_DEBUG("Full resource %s is released in RM %"PRIu64,
-                                                       res_name, _mm_rm_hash64(i_man->id));
-                                       break;
-                               }
-                       }
+                                                               j_man->is_released = TRUE;
+                                                               __add_cb_request(cb_requests, j_man, type,
+                                                                               g_array_index(res, mm_resource_manager_res_volume, 0));
 
-                       if (!is_released_fully) {
-                               for (i = 0,
-                                               enough_volume = request->volume + acquired_volume <=
-                                               conf->max_volume[request->type];
-                                               i < managers->len && !enough_volume; i++) {
+                                                               mm_resource_manager_backend_release(type);
+                                                               is_released_called_once = TRUE;
+                                                               break;
+                                                       }
+                                               }
+                                       }
 
-                                       i_man = (mm_resource_manager_dmn_p)managers->pdata[i];
-                                       if (manager == i_man ||
-                                                       !i_man->resources[request->type]->is_acquired ||
-                                                       conf->priority[i_man->app_class] >
-                                                       conf->priority[manager->app_class])
-                                               continue;
+                                       if (conf->max_instance[type] > 0 && !res)
+                                               res_count[type]++;
 
-                                       parts = i_man->resources[request->type]->parts;
-                                       while (parts->len > 0 && !enough_volume) {
+                                       i_man->resources[type]->is_acquired = TRUE;
 
-                                               __add_cb_request(cb_requests, i_man, request->type,
-                                                               g_array_index(parts,
-                                                               mm_resource_manager_res_volume, 0));
+                                       if (conf->max_instance[type] < res_count[type])
+                                               break;
 
-                                               acquired_volume -= g_array_index(parts,
-                                                               mm_resource_manager_res_volume, 0);
-                                               enough_volume = request->volume + acquired_volume <=
-                                                       conf->max_volume[request->type];
+                                       if (conf->volume_would_be_checked[type] && conf->max_volume[type] < 0
+                                               && acquired_volume < volume) {
+                                               for (j = 0; j < managers->len; j++) {
+                                                       j_man = (mm_resource_manager_dmn_p)managers->pdata[j];
+                                                       res = j_man->resources[type]->parts;
 
-                                               MM_RM_DEBUG("%d units of %s are released in RM %"PRIu64,
-                                                               g_array_index(parts,
-                                                               mm_resource_manager_res_volume, 0), res_name,
-                                                               _mm_rm_hash64(i_man->id));
+                                                       if (j_man->is_released)
+                                                               continue;
 
-                                               g_array_remove_index_fast(parts, 0);
+                                                       acquired_volume += g_array_index(res, mm_resource_manager_res_volume, 0);
+                                                       MM_RM_INFO("[#%d] [#%d / #%d] There are %d units of %s in RM %"PRIu64,
+                                                               managers->len, j + 1, res->len, acquired_volume, res_name,
+                                                               _mm_rm_hash64(j_man->id));
 
-                                               mm_resource_manager_backend_release(request->type);
-                                       }
+                                                       j_man->is_released = TRUE;
+                                                       __add_cb_request(cb_requests, j_man, type,
+                                                               g_array_index(res, mm_resource_manager_res_volume, 0));
+
+                                                       mm_resource_manager_backend_release(type);
 
-                                       if (!parts->len) {
-                                               MM_RM_DEBUG("Part array of %s is empty and will be "
-                                                               "freed in RM %"PRIu64, res_name,
-                                                               _mm_rm_hash64(i_man->id));
-                                               g_array_free(parts, TRUE);
-                                               i_man->resources[request->type]->parts = NULL;
-                                               i_man->resources[request->type]->is_acquired = FALSE;
+                                                       if (acquired_volume >= volume)
+                                                               break;
+                                               }
                                        }
+
+                                       continue;
                                }
                        }
 
-                       parts = manager->resources[request->type]->parts;
-                       if (parts == NULL) {
-                               parts = g_array_sized_new(FALSE, FALSE,
-                                               sizeof(mm_resource_manager_res_volume),
-                                               MM_RESOURCE_MANAGER_RESERVED_PART_ARRAY_SIZE);
-                               manager->resources[request->type]->parts = parts;
+                       res = manager->resources[requests->type]->parts;
+                       if (res == NULL) {
+                               res = g_array_sized_new(FALSE, FALSE, sizeof(mm_resource_manager_res_volume),
+                                       MM_RESOURCE_MANAGER_RESERVED_PART_ARRAY_SIZE);
+                               manager->resources[requests->type]->parts = res;
                        }
-                       g_array_append_val(parts, request->volume);
+                       g_array_append_val(res, requests->volume);
                }
 
-               manager->resources[request->type]->is_acquired = TRUE;
-               mm_resource_manager_backend_acquire(request->type);
+               manager->resources[type]->is_acquired = TRUE;
+               mm_resource_manager_backend_acquire(type);
        }
 
        return cb_requests;
@@ -681,55 +671,82 @@ static void __handle_release_callbacks(GArray *requests)
        int i;
        mm_resource_manager_id id;
        mm_resource_manager_dmn_release_cb_request_s *request;
+       mm_resource_manager_res_type_e type = MM_RESOURCE_MANAGER_RES_TYPE_MAX;
+       mm_resource_manager_res_volume volume = MM_RESOURCE_MANAGER_RES_VOLUME_FULL;
+       mm_resource_manager_conf_s *conf = mm_resource_manager_get_conf();
+
+       MM_RM_RETM_IF(requests == NULL, "requests is NULL");
+       MM_RM_RETM_IF(conf == NULL, "conf is NULL");
 
        for (i = 0; i < requests->len; i++) {
-               request = &g_array_index(requests,
-                               mm_resource_manager_dmn_release_cb_request_s, i);
+               request = &g_array_index(requests, mm_resource_manager_dmn_release_cb_request_s, i);
                id = request->manager->id;
                MM_RM_HASH64(id);
+               type = request->type;
+               volume = request->volume;
                MM_RM_DEBUG("Sending release callback to RM #%"PRIu64" for %s of volume %d",
-                               id, _mm_resource_manager_get_res_str(request->type),
-                               request->volume);
-               _mmrm_dmn_dbus_release_callback(id, request->type, request->volume);
+                               id, _mm_resource_manager_get_res_str(type), volume);
+               _mmrm_dmn_dbus_release_callback(id, type, volume);
                if (__wait_for_release_cb_sync(request->manager->id))
                        MM_RM_DEBUG("Release callback sync success");
                else
                        MM_RM_ERROR("Wait for release callback sync failed");
+
+               if (conf->volume_would_be_checked[type] && volume != MM_RESOURCE_MANAGER_RES_VOLUME_FULL) {
+                       conf->max_volume[type] += volume;
+                       MM_RM_INFO("type %d available volume + %d = %d", type, volume, conf->max_volume[type]);
+               }
+
+               if (conf->max_instance[type] > 0 && res_count[type] > 0) {
+                       res_count[type]--;
+                       MM_RM_INFO("The number of type %d #%d", type, res_count[type]);
+               }
        }
 }
 
 static void __handle_release_requests(mm_resource_manager_dmn_p manager,
                mm_resource_manager_dmn_res_request_s *requests)
 {
-       mm_resource_manager_dmn_res_request_p request;
        GArray *parts;
        int i;
+       mm_resource_manager_res_type_e type = MM_RESOURCE_MANAGER_RES_TYPE_MAX;
+       mm_resource_manager_res_volume volume = MM_RESOURCE_MANAGER_RES_VOLUME_FULL;
+       mm_resource_manager_conf_s *conf = mm_resource_manager_get_conf();
 
-       if (requests == NULL)
-               return;
+       MM_RM_RETM_IF(conf == NULL, "conf is NULL");
+       MM_RM_RETM_IF(requests == NULL, "requests is NULL");
 
        for (; requests->type != MM_RESOURCE_MANAGER_NO_RES; requests++) {
 
-               request = requests;
+               type = requests->type;
+               volume = requests->volume;
 
-               if (request->volume == MM_RESOURCE_MANAGER_RES_VOLUME_FULL) {
-                       manager->resources[request->type]->is_acquired = FALSE;
+               if (volume == MM_RESOURCE_MANAGER_RES_VOLUME_FULL) {
+                       manager->resources[type]->is_acquired = FALSE;
                } else {
-                       parts = manager->resources[request->type]->parts;
-                       for (i = 0; i < parts->len &&
-                                       ((mm_resource_manager_res_volume*)parts->data)[i] !=
-                                       request->volume; i++);
+                       parts = manager->resources[type]->parts;
+                       for (i = 0; i < parts->len && ((mm_resource_manager_res_volume*)parts->data)[i] != volume; i++);
 
                        g_array_remove_index_fast(parts, i);
 
                        if (parts->len == 0) {
                                g_array_free(parts, TRUE);
-                               manager->resources[request->type]->parts = NULL;
-                               manager->resources[request->type]->is_acquired = FALSE;
+                               manager->resources[type]->parts = NULL;
+                               manager->resources[type]->is_acquired = FALSE;
                        }
                }
 
-               mm_resource_manager_backend_release(request->type);
+               if (conf->volume_would_be_checked[type]) {
+                       conf->max_volume[type] += volume;
+                       MM_RM_INFO("[type %d] + %d = %d", type, volume, conf->max_volume[type]);
+               }
+
+               if (conf->max_instance[type] > 0) {
+                       res_count[type]--;
+                       MM_RM_INFO("The number of type %d #%d", type, res_count[type]);
+               }
+
+               mm_resource_manager_backend_release(type);
        }
 }
 
@@ -783,7 +800,8 @@ static gboolean __wait_for_release_cb_sync(mm_resource_manager_id id)
                         * the next sync.
                         */
                        sync.revents = 0;
-                       if (poll(&sync, 1, RELEASE_CB_SYNC_TIMEOUT * 1000) == 0 || (sync.revents & (POLLHUP | POLLERR)) == 0)
+                       if (poll(&sync, 1, RELEASE_CB_SYNC_TIMEOUT * 1000) == 0
+                               || (sync.revents & (POLLHUP | POLLERR)) == 0)
                                MM_RM_ERROR("The client didn't close the FIFO");
                } else {
                        MM_RM_ERROR("Read is failed (revents=%hd,read_size=%zd)", sync.revents, read_size);
index 5e48465..25d59bb 100644 (file)
@@ -43,4 +43,5 @@ mm_resource_manager_error_e _mmrm_dmn_commit(mm_resource_manager_id id,
                mm_resource_manager_dmn_res_request_s *acquires);
 void _mmrm_dmn_status_callback(mm_resource_manager_status_e status);
 
+
 #endif /* __MM_RESOURCE_MANAGER_DAEMON_PRIVATE__ */
index 2739901..93a8d94 100644 (file)
@@ -164,3 +164,14 @@ int mm_resource_manager_get_res_type_volume(mm_resource_manager_h rm,
 
        return _mm_resource_manager_get_res_type_volume(rm, type, condition, volume);
 }
+
+int mm_resource_manager_get_type_max_instance(mm_resource_manager_h rm,
+               mm_resource_manager_res_type_e type, int *max_instance)
+{
+       MM_RM_RETVM_IF(NULL == rm, MM_RESOURCE_MANAGER_ERROR_INVALID_PARAMETER, "Handle is NULL");
+       MM_RM_RETVM_IF(type < 0 || type >= MM_RESOURCE_MANAGER_RES_TYPE_MAX,
+                                       MM_RESOURCE_MANAGER_ERROR_INVALID_PARAMETER, "Wrong resource type");
+       MM_RM_RETVM_IF(max_instance == NULL, MM_RESOURCE_MANAGER_ERROR_INVALID_PARAMETER, "Max instance var is NULL");
+
+       return _mm_resource_manager_get_type_max_instance(rm, type, max_instance);
+}
index 4e186d9..004f942 100644 (file)
@@ -140,7 +140,7 @@ typedef enum {
        MM_RESOURCE_MANAGER_ERROR_NOT_SUPPORTED  = TIZEN_ERROR_NOT_SUPPORTED,                     /**< The feature is not supported */
        MM_RESOURCE_MANAGER_ERROR_INVALID_STATE,                                                  /**< Invalid state */
        MM_RESOURCE_MANAGER_ERROR_LOW_PRIORITY,                                                   /**< Low priority to acquire a resource */
-       MM_RESOURCE_MANAGER_ERROR_NOT_ENOUGH,                                                     /**< There are no enough free resource volume */
+       MM_RESOURCE_MANAGER_ERROR_NOT_ENOUGH,                                                     /**< There are not enough free resource volume */
        MM_RESOURCE_MANAGER_ERROR_LAUNCH_FAILURE,                                                 /**< Resource manager is not launched */
 } mm_resource_manager_error_e;
 
@@ -514,10 +514,32 @@ int mm_resource_manager_get_res_type_max_volume(mm_resource_manager_h rm,
  * @see mm_resource_manager_res_type_e
  * @see mm_resource_manager_res_type_cond_e
  */
-int mm_resource_manager_get_res_type_volume(mm_resource_manager_h rm,
-               mm_resource_manager_res_type_e type,
-               mm_resource_manager_res_type_cond_e condition,
-               mm_resource_manager_res_volume *volume);
+int mm_resource_manager_get_res_type_volume(mm_resource_manager_h rm, mm_resource_manager_res_type_e type,
+               mm_resource_manager_res_type_cond_e condition, mm_resource_manager_res_volume *volume);
+
+/**
+ * @brief Gets max instance number of resource part per specified resource @a type parameter.
+ * @since_tizen 5.5
+ * @remakrs This function may return reliable volumes for the same type.
+ *          #MM_RESOURCE_MANAGER_ERROR_INVALID_PARAMETER is
+ *          returned if there are no specified resource type or condition for
+ *          the platform.
+ * @param [in]  rm            Resource manager handle
+ * @param [in]  type          Resource type
+ * @param [out] max instance  max number of resource instance
+ * @return #MM_RESOURCE_MANAGER_ERROR_NONE on success,
+ *         otherwise error code value
+ * @retval #MM_RESOURCE_MANAGER_ERROR_NONE Successful
+ * @retval #MM_RESOURCE_MANAGER_ERROR_INVALID_PARAMETER Invalid parameter
+ * @retval #MM_RESOURCE_MANAGER_ERROR_NOT_SUPPORTED Resource type or condition
+ *         are not supported
+ * @pre @a rm must be created by calling mm_resource_manager_create()
+ * @see mm_resource_manager_create()
+ * @see mm_resource_manager_res_type_e
+ * @see mm_resource_manager_res_type_cond_e
+ */
+int mm_resource_manager_get_type_max_instance(mm_resource_manager_h rm,
+               mm_resource_manager_res_type_e type, int *max_instance);
 
 #ifdef __cplusplus
 }
index c3a7cdd..a3633d3 100644 (file)
@@ -66,6 +66,7 @@ typedef struct {
        mm_resource_manager_res_volume __condition_volumes
                [MM_RESOURCE_MANAGER_RES_TYPE_MAX]
                [MM_RESOURCE_MANAGER_RES_TYPE_COND_MAX];
+       int __max_instance[MM_RESOURCE_MANAGER_RES_TYPE_MAX];
 
        MMResourceManager *dbus_proxy;
 
@@ -478,6 +479,20 @@ int _mm_resource_manager_get_res_type_volume(mm_resource_manager_h rm,
        }
 }
 
+int _mm_resource_manager_get_type_max_instance(mm_resource_manager_h rm,
+               mm_resource_manager_res_type_e type, int *max_instance)
+{
+       mm_resource_manager_s *handle = MM_RESOURCE_MANAGER(rm);
+
+       if (handle->__max_instance[type] == MM_RESOURCE_MANAGER_NO_RES) {
+               MM_RM_DEBUG("No resource for the platform");
+               return MM_RESOURCE_MANAGER_ERROR_NOT_SUPPORTED;
+       }
+
+       *max_instance = handle->__max_instance[type];
+       return MM_RESOURCE_MANAGER_ERROR_NONE;
+}
+
 void __mm_resource_manager_release_callback(mm_resource_manager_s *handle,
                mm_resource_manager_id id,
                mm_resource_manager_res_type_e type,
@@ -486,9 +501,9 @@ void __mm_resource_manager_release_callback(mm_resource_manager_s *handle,
        mm_resource_manager_res_s *resource;
        mm_resource_manager_id handle_id;
        gboolean release_all = FALSE;
-       int j;
+       int i;
 
-       MM_RM_DEBUG("Release callback is emitted for %s of volume %d in RM #%"PRIu64,
+       MM_RM_INFO("Release callback is emitted for %s of volume %d in RM #%"PRIu64,
                        _mm_resource_manager_get_res_str(type), volume, id);
 
        handle_id = handle->id;
@@ -496,8 +511,9 @@ void __mm_resource_manager_release_callback(mm_resource_manager_s *handle,
        if (handle_id == id) {
                __mm_resources_lock(handle);
                __mm_resource_handles_unlock();
-               for (j = 0; j < handle->resources->len; j++) {
-                       resource = (mm_resource_manager_res_s*)handle->resources->pdata[j];
+
+               for (i = 0; i < handle->resources->len; i++) {
+                       resource = (mm_resource_manager_res_s*)handle->resources->pdata[i];
                        if (resource->type == type && resource->volume == volume) {
 
                                release_all = ((mm_resource_manager_release_cb)
@@ -506,7 +522,7 @@ void __mm_resource_manager_release_callback(mm_resource_manager_s *handle,
 
                                __send_release_cb_sync(handle->id);
 
-                               g_ptr_array_remove_index_fast(handle->resources, j);
+                               g_ptr_array_remove_index_fast(handle->resources, i);
                                break;
                        }
                }
@@ -539,20 +555,17 @@ void __mm_resource_manager_status_callback(mm_resource_manager_s *handle,
 
 static void __mm_resource_handles_lock(void)
 {
-       MM_RM_INFO("handles lock");
        g_mutex_lock(&handles_lock);
 }
 
 static void __mm_resource_handles_unlock(void)
 {
        g_mutex_unlock(&handles_lock);
-       MM_RM_INFO("handles unlocked");
 }
 
 static void __mm_resources_lock(mm_resource_manager_s *h)
 {
        MM_RM_RETM_IF(!h, "handle is NULL");
-       MM_RM_INFO("[handle %p]resources lock", h);
        g_mutex_lock(&h->resources_lock);
 }
 
@@ -560,7 +573,6 @@ static void __mm_resources_unlock(mm_resource_manager_s *h)
 {
        MM_RM_RETM_IF(!h, "handle is NULL");
        g_mutex_unlock(&h->resources_lock);
-       MM_RM_INFO("[handle %p]resources unlocked", h);
 }
 
 static int __check_resource(mm_resource_manager_s *rm,
@@ -577,10 +589,6 @@ static int __check_resource(mm_resource_manager_s *rm,
                        "No resource for the platform");
 
        if (volume > 0) {
-               MM_RM_RETVM_IF(remaining_local_volume < volume,
-                               MM_RESOURCE_MANAGER_ERROR_INVALID_OPERATION,
-                               "Requested volume %d exceeds max value %d", volume,
-                               remaining_local_volume);
                for (i = 0; i < rm->resources->len; i++) {
                        i_res = (mm_resource_manager_res_p) rm->resources->pdata[i];
                        if (i_res->type == type &&
@@ -605,8 +613,11 @@ static int __create_resource(mm_resource_manager_s *rm,
 {
        int ret;
 
-       MM_RM_RETVM_IF(res == NULL, MM_RESOURCE_MANAGER_ERROR_INVALID_PARAMETER,
-                       "NULL pointer");
+       mm_resource_manager_s *handle = MM_RESOURCE_MANAGER(rm);
+
+       MM_RM_RETVM_IF(handle == NULL, MM_RESOURCE_MANAGER_ERROR_INVALID_PARAMETER,
+                       "NULL handle pointer");
+       MM_RM_RETVM_IF(res == NULL, MM_RESOURCE_MANAGER_ERROR_INVALID_PARAMETER, "NULL pointer");
        ret = __check_resource(rm, type, volume);
        if (ret != MM_RESOURCE_MANAGER_ERROR_NONE)
                return ret;
@@ -623,14 +634,14 @@ static void __destroy_resource(void *res)
        g_free(res);
 }
 
-static int __get_resource_index(mm_resource_manager_s *rm,
-               mm_resource_manager_res_p res)
+static int __get_resource_index(mm_resource_manager_s *rm, mm_resource_manager_res_p res)
 {
        int i;
 
-       for (i = 0; i < rm->resources->len; i++)
+       for (i = 0; i < rm->resources->len; i++) {
                if (rm->resources->pdata[i] == (gpointer) res)
                        return i;
+       }
 
        return MM_RESOURCE_MANAGER_RES_NOT_FOUND;
 }
@@ -658,9 +669,10 @@ static gboolean __check_rm_handle(mm_resource_manager_s *handle)
 {
        int i;
 
-       for (i = 0; i < handles->len; i++)
+       for (i = 0; i < handles->len; i++) {
                if (g_ptr_array_index(handles, i) == handle)
                        return TRUE;
+       }
        return FALSE;
 }
 
@@ -681,8 +693,7 @@ static void __send_release_cb_sync(mm_resource_manager_id id)
 
 static void __init_lib()
 {
-       handles = g_ptr_array_sized_new(
-                       MM_RESOURCE_MANAGER_RESERVED_HANDLE_ARRAY_SIZE);
+       handles = g_ptr_array_sized_new(MM_RESOURCE_MANAGER_RESERVED_HANDLE_ARRAY_SIZE);
        MM_RM_RETM_IF(handles == NULL, "API lib cannot be initialized");
 
        MM_RM_INFO("API lib is loaded");
@@ -746,38 +757,31 @@ static int __dbus_init_conf(mm_resource_manager_s *handle)
        int rm_error = MM_RESOURCE_MANAGER_ERROR_NONE;
        GVariant *max_volume = NULL;
        GVariant *cond_volume = NULL;
+       GVariant *max_instance = NULL;
        GVariant *tmp;
        GVariantIter volume_iter;
        GVariantIter cond_volume_iter;
 
-       mmresource_manager_call_conf_sync(handle->dbus_proxy, &rm_error,
-                       &max_volume, &cond_volume, NULL, &error);
+       mmresource_manager_call_conf_sync(handle->dbus_proxy, &rm_error, &max_volume,
+                       &cond_volume, &max_instance, NULL, &error);
        MM_RM_RET_IF_GERR(error, "DBus conf msg cannot be sent");
 
        MM_RM_RETVM_IF(max_volume == NULL || cond_volume == NULL,
-                       MM_RESOURCE_MANAGER_ERROR_INVALID_OPERATION,
-                       "Variant data are empty");
+                       MM_RESOURCE_MANAGER_ERROR_INVALID_OPERATION, "Variant data are empty");
 
-       if (g_variant_iter_init(&volume_iter, max_volume) ==
-                       MM_RESOURCE_MANAGER_RES_TYPE_MAX) {
-               for (i = 0; g_variant_iter_next(&volume_iter, "i",
-                               &handle->__max_resource_volumes[i]); i++);
+       if (g_variant_iter_init(&volume_iter, max_volume) == MM_RESOURCE_MANAGER_RES_TYPE_MAX) {
+               for (i = 0; g_variant_iter_next(&volume_iter, "i", &handle->__max_resource_volumes[i]); i++);
                g_variant_unref(max_volume);
+               max_volume = NULL;
        } else {
-               g_variant_unref(max_volume);
-               g_variant_unref(cond_volume);
                MM_RM_ERROR("Wrong max volume array size");
-               return MM_RESOURCE_MANAGER_ERROR_INVALID_OPERATION;
+               goto out;
        }
 
-       if (g_variant_iter_init(&volume_iter, cond_volume) ==
-                       MM_RESOURCE_MANAGER_RES_TYPE_MAX) {
-               for (i = 0; (tmp = g_variant_iter_next_value(&volume_iter)) != NULL;
-                               i++) {
-                       if (g_variant_iter_init(&cond_volume_iter, tmp) ==
-                                       MM_RESOURCE_MANAGER_RES_TYPE_COND_MAX) {
-                               for (j = 0; g_variant_iter_next(&cond_volume_iter, "i",
-                                               &handle->__condition_volumes[i][j]); j++);
+       if (g_variant_iter_init(&volume_iter, cond_volume) == MM_RESOURCE_MANAGER_RES_TYPE_MAX) {
+               for (i = 0; (tmp = g_variant_iter_next_value(&volume_iter)) != NULL; i++) {
+                       if (g_variant_iter_init(&cond_volume_iter, tmp) == MM_RESOURCE_MANAGER_RES_TYPE_COND_MAX) {
+                               for (j = 0; g_variant_iter_next(&cond_volume_iter, "i", &handle->__condition_volumes[i][j]); j++);
                                g_variant_unref(tmp);
                        } else {
                                g_variant_unref(tmp);
@@ -787,17 +791,30 @@ static int __dbus_init_conf(mm_resource_manager_s *handle)
                        }
                }
                g_variant_unref(cond_volume);
+               cond_volume = NULL;
        } else {
-               g_variant_unref(cond_volume);
                MM_RM_ERROR("Wrong condition volume array size");
-               return MM_RESOURCE_MANAGER_ERROR_INVALID_OPERATION;
+               goto out;
+       }
+
+       if (g_variant_iter_init(&volume_iter, max_instance) == MM_RESOURCE_MANAGER_RES_TYPE_MAX) {
+               for (i = 0; g_variant_iter_next(&volume_iter, "i", &handle->__max_instance[i]); i++);
+               g_variant_unref(max_instance);
+               max_instance = NULL;
+       } else {
+               MM_RM_ERROR("Wrong max instance array size");
+               goto out;
        }
 
        return rm_error;
+out:
+       g_variant_unref(max_volume);
+       g_variant_unref(cond_volume);
+       g_variant_unref(max_instance);
+       return MM_RESOURCE_MANAGER_ERROR_INVALID_OPERATION;
 }
 
-static int __dbus_create(mm_resource_manager_s *handle,
-               mm_resource_manager_app_class_e app_class)
+static int __dbus_create(mm_resource_manager_s *handle, mm_resource_manager_app_class_e app_class)
 {
        GError *error = NULL;
        int rm_error = MM_RESOURCE_MANAGER_ERROR_NONE;
@@ -843,6 +860,7 @@ static int __dbus_commit(mm_resource_manager_s *handle)
 
        release_builder = g_variant_builder_new(G_VARIANT_TYPE_ARRAY);
        acquire_builder = g_variant_builder_new(G_VARIANT_TYPE_ARRAY);
+
        for (i = 0; i < handle->resources->len; i++) {
                resource = (mm_resource_manager_res_p) handle->resources->pdata[i];
 
@@ -865,7 +883,8 @@ static int __dbus_commit(mm_resource_manager_s *handle)
        if (release_num + acquire_num == 0) {
                g_variant_builder_unref(release_builder);
                g_variant_builder_unref(acquire_builder);
-               MM_RM_DEBUG("There is nothing to commit - dbus request is not sent");
+               MM_RM_DEBUG("There is nothing to commit - dbus request is not sent [%d %d]",
+                               release_num, acquire_num);
                return rm_error;
        }
 
@@ -927,13 +946,17 @@ static void __dbus_release_callback(MMResourceManager *object, guint64 arg_id,
                gint arg_resource_type, gint arg_volume)
 {
        mm_resource_manager_s *handle;
+       mm_resource_manager_id handle_id;
        gboolean unlock = TRUE;
        int i;
 
        __mm_resource_handles_lock();
+
        for (i = 0; i < handles->len; i++) {
                handle = (mm_resource_manager_s*)handles->pdata[i];
-               if (handle->dbus_proxy == object) {
+               handle_id = handle->id;
+               MM_RM_HASH64(handle_id);
+               if (handle->dbus_proxy == object && handle_id == arg_id) {
                        __mm_resource_manager_release_callback(handle, arg_id,
                                        arg_resource_type, arg_volume);
                        unlock = FALSE;
@@ -951,6 +974,7 @@ static void __dbus_status_callback(MMResourceManager *object, gint arg_status)
        gboolean unlock = TRUE;
        int i;
 
+       MM_RM_INFO("status callback status %d", arg_status);
        __mm_resource_handles_lock();
        for (i = 0; i < handles->len; i++) {
                handle = (mm_resource_manager_s*)handles->pdata[i];
index 5532708..10e3ac7 100644 (file)
@@ -53,5 +53,7 @@ int _mm_resource_manager_get_res_type_volume(mm_resource_manager_h rm,
                mm_resource_manager_res_type_e type,
                mm_resource_manager_res_type_cond_e condition,
                mm_resource_manager_res_volume *volume);
+int _mm_resource_manager_get_type_max_instance(mm_resource_manager_h rm,
+               mm_resource_manager_res_type_e type, int *max_instance);
 
 #endif /* __MM_RESOURCE_MANAGER_PRIVATE__ */
index a2473a0..e0d3076 100644 (file)
@@ -52,7 +52,7 @@ typedef enum {
 
 
 
-static const charresource_str[MM_RESOURCE_MANAGER_RES_TYPE_MAX + 1] = {
+static const char *resource_str[MM_RESOURCE_MANAGER_RES_TYPE_MAX + 1] = {
        "video_decoder(#0)",
        "video_overlay(#1)",
        "camera(#2)",
@@ -62,18 +62,18 @@ static const char* resource_str[MM_RESOURCE_MANAGER_RES_TYPE_MAX + 1] = {
        NULL
 };
 
-static const charapp_class_str[MM_RESOURCE_MANAGER_APP_CLASS_MAX + 1] = {
+static const char *app_class_str[MM_RESOURCE_MANAGER_APP_CLASS_MAX + 1] = {
        "media",
        "interrupt",
        NULL
 };
 
-static const charstatus_str[MM_RESOURCE_MANAGER_STATUS_MAX + 1] = {
+static const char *status_str[MM_RESOURCE_MANAGER_STATUS_MAX + 1] = {
        "disconnected",
        NULL
 };
 
-static const charcondition_str[MM_RESOURCE_MANAGER_RES_TYPE_COND_MAX + 1] = {
+static const char *condition_str[MM_RESOURCE_MANAGER_RES_TYPE_COND_MAX + 1] = {
        "SD",
        "HD",
        "FHD",
@@ -81,9 +81,9 @@ static const char* condition_str[MM_RESOURCE_MANAGER_RES_TYPE_COND_MAX + 1] = {
        NULL
 };
 
-static const charres_state_str[MM_RESOURCE_MANAGER_RES_STATE_FOR_RELEASE + 2] = {
+static const char *res_state_str[MM_RESOURCE_MANAGER_RES_STATE_FOR_RELEASE + 2] = {
        "FOR ACQUIRE",
-       "ACQUIRED   ",
+       "ACQUIRED",
        "FOR RELEASE",
        NULL
 };
@@ -146,12 +146,10 @@ static int release_cb(mm_resource_manager_h rm,
 
        g_mutex_lock(&sync_mutex);
        resources = g_hash_table_lookup(resource_managers, rm);
-       if (resources) {
+       if (resources)
                g_hash_table_remove(resources, resource_h);
-       } else {
-               g_print("WARNING: resource manager %p was removed during the release "
-                               "cb call. Nothing is done.", rm);
-       }
+       else
+               g_print("WARNING: resource manager %p was removed during the release cb call. Nothing is done.", rm);
        g_mutex_unlock(&sync_mutex);
        return FALSE;
 }
@@ -324,8 +322,7 @@ static void display_conditions(gchar **cmd_tokens)
 
        if (!max_cond_width) {
                max_res_width = get_max_str_len(resource_str);
-               align = (MAX_CMD_LINE_LEN - max_res_width) /
-                               MM_RESOURCE_MANAGER_RES_TYPE_COND_MAX;
+               align = (MAX_CMD_LINE_LEN - max_res_width) / MM_RESOURCE_MANAGER_RES_TYPE_COND_MAX;
                max_cond_width = get_max_str_len(condition_str);
                if (align > max_cond_width)
                        max_cond_width = align;
@@ -433,8 +430,7 @@ static gpointer get_resource_by_index(mm_resource_manager_h rm, int i)
        gpointer *reses;
        guint len;
 
-       reses = g_hash_table_get_keys_as_array(
-                       g_hash_table_lookup(resource_managers, rm), &len);
+       reses = g_hash_table_get_keys_as_array(g_hash_table_lookup(resource_managers, rm), &len);
 
        res = i < len ? reses[i] : NULL;
 
@@ -443,8 +439,7 @@ static gpointer get_resource_by_index(mm_resource_manager_h rm, int i)
        return res;
 }
 
-static mm_resource_manager_res_h get_resource_from_cmd(gchar **cmd_tokens,
-               mm_resource_manager_h rm)
+static mm_resource_manager_res_h get_resource_from_cmd(gchar **cmd_tokens, mm_resource_manager_h rm)
 {
        mm_resource_manager_res_h res;
        int res_i;
@@ -617,8 +612,7 @@ static void process_mark_for_release_cmd(gchar **cmd_tokens)
 
        g_mutex_lock(&sync_mutex);
        resources = g_hash_table_lookup(resource_managers, rm);
-       state_p = (mm_resource_manager_res_state_e *)g_hash_table_lookup(
-                       resources, resource);
+       state_p = (mm_resource_manager_res_state_e *)g_hash_table_lookup(resources, resource);
        err = mm_resource_manager_mark_for_release(rm, resource);
        if (err == MM_RESOURCE_MANAGER_ERROR_NONE) {
 
@@ -635,18 +629,14 @@ static void process_mark_for_release_cmd(gchar **cmd_tokens)
        g_mutex_unlock(&sync_mutex);
 }
 
-static gboolean is_marked_for_acquire(gpointer resource, gpointer state,
-               gpointer user_data)
+static gboolean is_marked_for_acquire(gpointer resource, gpointer state, gpointer user_data)
 {
-       return *((mm_resource_manager_res_state_e *)state) ==
-                       MM_RESOURCE_MANAGER_RES_STATE_FOR_ACQUIRE;
+       return *((mm_resource_manager_res_state_e *)state) == MM_RESOURCE_MANAGER_RES_STATE_FOR_ACQUIRE;
 }
 
-static void mark_all_for_release(gpointer resource, gpointer state, gpointer
-               user_data)
+static void mark_all_for_release(gpointer resource, gpointer state, gpointer user_data)
 {
-       mm_resource_manager_res_state_e *state_p =
-                       (mm_resource_manager_res_state_e *)state;
+       mm_resource_manager_res_state_e *state_p = (mm_resource_manager_res_state_e *)state;
        if (*state_p == MM_RESOURCE_MANAGER_RES_STATE_ACQUIRED)
                *state_p = MM_RESOURCE_MANAGER_RES_STATE_FOR_RELEASE;
 }
@@ -749,8 +739,7 @@ static void process_commit_cmd(gchar **cmd_tokens)
                g_print("Changes in RM %p were committed successfully\n", rm);
                break;
        case MM_RESOURCE_MANAGER_ERROR_LOW_PRIORITY:
-               print_api_error("Commit couldn't be done because of resource conflict",
-                               err);
+               print_api_error("Commit couldn't be done because of resource conflict", err);
                break;
        default:
                print_api_error("Commit couldn't be done", err);
@@ -786,8 +775,7 @@ static gboolean input(GIOChannel *channel)
        GString *cmd_line;
 
        cmd_line = g_string_new(NULL);
-       if (g_io_channel_read_line_string(channel, cmd_line, &read_size, &error) !=
-                       G_IO_STATUS_NORMAL)
+       if (g_io_channel_read_line_string(channel, cmd_line, &read_size, &error) != G_IO_STATUS_NORMAL)
                return TRUE;
 
        g_strstrip(cmd_line->str);
@@ -903,8 +891,7 @@ int main(int argc, char *argv[])
        int option;
 
        if (!check_const_string_arrays()) {
-               g_print("FATAL ERROR: Resource manager API was changed. "
-                               "The test suite must be changed too.\n");
+               g_print("FATAL ERROR: Resource manager API was changed. The test suite must be changed too.\n");
                return 1;
        }
 
@@ -912,9 +899,7 @@ int main(int argc, char *argv[])
                switch (option) {
                case '?':
                case 'h':
-                       g_print("Usage: %s [-s]\n"
-                                       "   s - don't display menu\n"
-                                       "   ?,h - usage\n", argv[0]);
+                       g_print("Usage: %s [-s]\n   s - don't display menu\n   ?,h - usage\n", argv[0]);
                        return 0;
                case 's':
                        skip_menu = TRUE;
@@ -927,8 +912,7 @@ int main(int argc, char *argv[])
        g_io_channel_set_flags(stdin_channel, G_IO_FLAG_NONBLOCK, NULL);
        g_io_add_watch(stdin_channel, G_IO_IN, (GIOFunc) input, NULL);
 
-       resource_managers = g_hash_table_new_full(NULL, NULL,
-                       free_resource_manager, free_resources);
+       resource_managers = g_hash_table_new_full(NULL, NULL, free_resource_manager, free_resources);
 
        display_menu();