2 * Copyright (c) 2017 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
22 #include "lib/mm_resource_manager.h"
27 TEST_COMMAND_CREATE = 'c',
28 TEST_COMMAND_DESTROY = 'd',
29 TEST_COMMAND_MARK_ACQUIRE = 'a',
30 TEST_COMMAND_MARK_RELEASE = 'r',
31 TEST_COMMAND_MARK_RELEASE_ALL = 'R',
32 TEST_COMMAND_MARK_RESIZE = 's',
33 TEST_COMMAND_COMMIT = 'm',
34 TEST_COMMAND_APP_CLASS_LIST = 'p',
35 TEST_COMMAND_RES_TYPE_LIST = 't',
36 TEST_COMMAND_RES_TYPE_COND_LIST = 'n',
37 TEST_COMMAND_STATUS = 'u'
41 MM_RESOURCE_MANAGER_RES_STATE_FOR_ACQUIRE, /* uncommitted */
42 MM_RESOURCE_MANAGER_RES_STATE_ACQUIRED, /* committed */
43 MM_RESOURCE_MANAGER_RES_STATE_FOR_RELEASE /* uncommitted */
44 } mm_resource_manager_res_state_e;
48 #define MAX_CMD_LINE_LEN 80
50 #define GET_ENUM_STR(val, str_a) \
51 ((val >= 0 && val < sizeof(str_a) / sizeof(str_a[0])) ? str_a[val] : "(!)unknown")
55 static const char *resource_str[MM_RESOURCE_MANAGER_RES_TYPE_MAX + 1] = {
65 static const char *app_class_str[MM_RESOURCE_MANAGER_APP_CLASS_MAX + 1] = {
71 static const char *status_str[MM_RESOURCE_MANAGER_STATUS_MAX + 1] = {
76 static const char *condition_str[MM_RESOURCE_MANAGER_RES_TYPE_COND_MAX + 1] = {
84 static const char *res_state_str[MM_RESOURCE_MANAGER_RES_STATE_FOR_RELEASE + 2] = {
93 static GMainLoop *loop;
94 static GHashTable *resource_managers;
95 static gboolean auto_destroy_manager = TRUE;
96 static GMutex sync_mutex;
97 static gboolean skip_menu = FALSE;
101 static void print_api_error(char *msg, mm_resource_manager_error_e err)
106 case MM_RESOURCE_MANAGER_ERROR_NONE:
107 err_str = "no error";
109 case MM_RESOURCE_MANAGER_ERROR_INVALID_PARAMETER:
110 err_str = "invalid parameter";
112 case MM_RESOURCE_MANAGER_ERROR_INVALID_OPERATION:
113 err_str = "invalid operation";
115 case MM_RESOURCE_MANAGER_ERROR_NOT_SUPPORTED:
116 err_str = "not supported";
118 case MM_RESOURCE_MANAGER_ERROR_INVALID_STATE:
119 err_str = "invalid state";
121 case MM_RESOURCE_MANAGER_ERROR_LOW_PRIORITY:
122 err_str = "low priority";
124 case MM_RESOURCE_MANAGER_ERROR_NOT_ENOUGH:
125 err_str = "not enough volume";
128 err_str = "unknown error";
131 g_print("API ERROR: %d (%s) - %s", err, err_str, msg);
134 static void print_error(char *msg)
136 g_print("ERROR: %s", msg);
139 static int release_cb(mm_resource_manager_h rm,
140 mm_resource_manager_res_h resource_h, void *user_data)
142 GHashTable *resources;
144 g_print("Release cb of resource manager %p is called for resource "
145 "%p\n", rm, resource_h);
147 g_mutex_lock(&sync_mutex);
148 resources = g_hash_table_lookup(resource_managers, rm);
150 g_hash_table_remove(resources, resource_h);
152 g_print("WARNING: resource manager %p was removed during the release cb call. Nothing is done.", rm);
153 g_mutex_unlock(&sync_mutex);
157 static void status_cb(mm_resource_manager_h rm, mm_resource_manager_status_e status,
160 g_print("Status cb of resource manager %p is called with status %d (%s)\n",
161 rm, status, status_str[status]);
163 g_mutex_lock(&sync_mutex);
164 if (g_hash_table_lookup(resource_managers, rm)) {
167 case MM_RESOURCE_MANAGER_STATUS_DISCONNECTED:
168 g_print("Resource manager %p cannot be used anymore and must be"
169 " destroyed.\n", rm);
175 g_print("WARNING: resource manager %p was removed during the status "
178 g_mutex_unlock(&sync_mutex);
181 static int get_max_str_len(const char *strs[])
187 for (i = 0; strs[i]; i++) {
188 len = strlen(strs[i]);
196 static int counter(gboolean reset)
198 static int counter = 1;
207 static void display_menu_head(gchar *title)
212 for (i = 0; i < MAX_CMD_LINE_LEN; i++)
214 g_print("\n %s\n", title);
215 for (i = 0; i < MAX_CMD_LINE_LEN; i++)
220 static void display_menu_tail(gboolean input)
224 for (i = 0; i < MAX_CMD_LINE_LEN; i++)
227 for (i = 0; i < MAX_CMD_LINE_LEN; i++)
234 static void display_app_classes()
238 display_menu_head("Application Classes");
240 for (i = 0; i < MM_RESOURCE_MANAGER_APP_CLASS_MAX; i++)
241 g_print("%d - %s\n", i, app_class_str[i]);
243 display_menu_tail(FALSE);
246 static gpointer get_manager_by_index(int i)
252 mans = g_hash_table_get_keys_as_array(resource_managers, &len);
254 man = i < len ? mans[i] : NULL;
261 static mm_resource_manager_h get_manager_from_cmd(gchar **cmd_tokens)
263 mm_resource_manager_h rm;
266 if (!cmd_tokens[1]) {
267 print_error("Resource manager number was not specified");
271 manager_i = g_ascii_strtoull(cmd_tokens[1], NULL, 10);
272 if (!manager_i && g_strcmp0(cmd_tokens[1], "0")) {
273 print_error("Resource manager number is not unsigned integer");
277 rm = get_manager_by_index(manager_i - 1);
279 print_error("Resource manager number is out of bounds");
286 static void display_resource_types(gchar **cmd_tokens)
289 mm_resource_manager_res_volume volume;
290 mm_resource_manager_h rm;
291 static int max_res_len = 0;
294 max_res_len = get_max_str_len(resource_str);
296 rm = get_manager_from_cmd(cmd_tokens);
300 display_menu_head("Resource Types (Max Volume)");
302 for (i = 0; i < MM_RESOURCE_MANAGER_RES_TYPE_MAX; i++) {
303 mm_resource_manager_get_res_type_max_volume(rm, i, &volume);
304 g_print("%d - %*s %d\n", i, max_res_len, resource_str[i], volume);
307 display_menu_tail(FALSE);
310 static void display_conditions(gchar **cmd_tokens)
314 mm_resource_manager_res_volume volume;
315 static int max_cond_width = 0;
316 static int max_res_width = 0;
317 mm_resource_manager_h rm;
319 rm = get_manager_from_cmd(cmd_tokens);
323 if (!max_cond_width) {
324 max_res_width = get_max_str_len(resource_str);
325 align = (MAX_CMD_LINE_LEN - max_res_width) / MM_RESOURCE_MANAGER_RES_TYPE_COND_MAX;
326 max_cond_width = get_max_str_len(condition_str);
327 if (align > max_cond_width)
328 max_cond_width = align;
331 display_menu_head("Resource Conditions");
333 g_print("%*s", max_res_width, "type/cond");
334 for (j = 0; j < MM_RESOURCE_MANAGER_RES_TYPE_COND_MAX; j++)
335 g_print("%*s", max_cond_width, condition_str[j]);
339 for (i = 0; i < MM_RESOURCE_MANAGER_RES_TYPE_MAX; i++) {
340 g_print("%*s", max_res_width, resource_str[i]);
341 for (j = 0; j < MM_RESOURCE_MANAGER_RES_TYPE_COND_MAX; j++) {
342 if (mm_resource_manager_get_res_type_volume(rm, i, j, &volume) ==
343 MM_RESOURCE_MANAGER_ERROR_NONE)
344 g_print("%*d", max_cond_width, volume);
346 g_print("%*s", max_cond_width, "-");
351 display_menu_tail(FALSE);
354 static void display_manager_resource(gpointer resource, gpointer state,
357 mm_resource_manager_h rm = user_data;
358 mm_resource_manager_res_h res = resource;
359 mm_resource_manager_res_info_s res_info;
361 g_print("%*d.%*s", INDENT, counter(FALSE), INDENT, " ");
362 if (mm_resource_manager_get_resource_info(rm, res, &res_info) ==
363 MM_RESOURCE_MANAGER_ERROR_NONE) {
364 g_print("%p %s (%s, %d, %s)\n", res,
365 GET_ENUM_STR(*((mm_resource_manager_res_state_e*)state), res_state_str),
366 GET_ENUM_STR(res_info.type, resource_str),
367 res_info.volume, res_info.is_acquire_failed ? "TRUE" : "FALSE");
369 g_print("(!) Can't get resource info\n");
373 static void display_manager(gpointer manager, gpointer resources, gpointer user_data)
375 int *number_p = user_data;
377 if (g_hash_table_size(resources)) {
378 g_print("%d. manager %p resources:\n", (*number_p)++, manager);
380 g_hash_table_foreach(resources, display_manager_resource, manager);
382 g_print("%d. manager %p\n", (*number_p)++, manager);
386 static void display_manager_list()
390 display_menu_head("Existing Resource Managers");
391 g_mutex_lock(&sync_mutex);
392 g_hash_table_foreach(resource_managers, display_manager, &number);
393 g_mutex_unlock(&sync_mutex);
394 display_menu_tail(FALSE);
397 static void display_menu()
402 display_menu_head("MM Resource Manager Test Suite: Main menu");
405 * <app class> - int value of mm_resource_manager_app_class_e
406 * <manager number> - number returned by the status command
407 * <numeric resource type> - int value of mm_resource_manager_res_type_e
408 * <volume> - int value; -1 means full volume of resource
409 * <resource number> - number returned by the status command
411 g_print("c - Create Resource Manager <app class>\n");
412 g_print("d - Destroy Resource Manager <manager number>\n");
413 g_print("a - Mark For Acquire <manager number> <numeric resource type> <volume>\n");
414 g_print("r - Mark For Release <manager number> <resource number>\n");
415 g_print("R - Mark All For Release <manager number>\n");
416 g_print("s - Resize Marked <manager number> <resource number> <volume>\n");
417 g_print("m - Commit <manager number>\n");
418 g_print("p - Print Application Classes\n");
419 g_print("t - Print Resource Types <manager number>\n");
420 g_print("n - Print Resource Conditions <manager number>\n");
421 g_print("u - Print Resource Manager List and Status\n");
422 g_print("q - Quit\n");
424 display_menu_tail(TRUE);
427 static gpointer get_resource_by_index(mm_resource_manager_h rm, int i)
433 reses = g_hash_table_get_keys_as_array(g_hash_table_lookup(resource_managers, rm), &len);
435 res = i < len ? reses[i] : NULL;
442 static mm_resource_manager_res_h get_resource_from_cmd(gchar **cmd_tokens, mm_resource_manager_h rm)
444 mm_resource_manager_res_h res;
447 if (!cmd_tokens[2]) {
448 print_error("Resource number was not specified");
452 res_i = g_ascii_strtoull(cmd_tokens[2], NULL, 10);
453 if (!res_i && g_strcmp0(cmd_tokens[2], "0")) {
454 print_error("Resource number is not unsigned integer");
458 res = get_resource_by_index(rm, res_i - 1);
460 print_error("Resource number is out of bounds");
467 static gboolean get_resource_type_from_cmd(gchar **cmd_tokens, int *res_p)
469 if (!cmd_tokens[2]) {
470 print_error("Resource was not specified");
474 *res_p = g_ascii_strtoull(cmd_tokens[2], NULL, 10);
475 if (!*res_p && g_strcmp0(cmd_tokens[2], "0")) {
476 print_error("Resource is not integer");
483 static gboolean get_volume_from_cmd(gchar **cmd_tokens, int *res_p)
485 if (!cmd_tokens[3]) {
486 print_error("Resource volume was not specified");
490 *res_p = g_ascii_strtoull(cmd_tokens[3], NULL, 10);
491 if (!*res_p && g_strcmp0(cmd_tokens[3], "0")) {
492 print_error("Resource volume is not integer");
499 static void free_resource_state(void *res_state_p)
504 static void process_create_cmd(gchar **cmd_tokens)
507 mm_resource_manager_error_e err;
508 mm_resource_manager_h rm;
510 if (!cmd_tokens[1]) {
511 print_error("Application class was not specified");
515 app_class = g_ascii_strtoull(cmd_tokens[1], NULL, 10);
516 if (!app_class && g_strcmp0(cmd_tokens[1], "0")) {
517 print_error("Application class is not unsigned integer");
521 err = mm_resource_manager_create(app_class, release_cb, NULL, &rm);
522 if (err == MM_RESOURCE_MANAGER_ERROR_NONE) {
523 if (mm_resource_manager_set_status_cb(rm, status_cb, NULL) ==
524 MM_RESOURCE_MANAGER_ERROR_NONE) {
525 g_mutex_lock(&sync_mutex);
526 g_hash_table_insert(resource_managers, rm,
527 g_hash_table_new_full(NULL, NULL, NULL, free_resource_state));
528 g_mutex_unlock(&sync_mutex);
529 g_print("Resource manager %p of class '%s' created successfully\n",
530 rm, GET_ENUM_STR(app_class, app_class_str));
532 mm_resource_manager_destroy(rm);
533 print_api_error("Resource manager couldn't be created. "
534 "Could not set callbacks", err);
537 print_api_error("Resource manager couldn't be created", err);
541 static void process_destroy_cmd(gchar **cmd_tokens)
543 mm_resource_manager_error_e err;
544 mm_resource_manager_h rm;
546 rm = get_manager_from_cmd(cmd_tokens);
550 err = mm_resource_manager_destroy(rm);
551 if (err == MM_RESOURCE_MANAGER_ERROR_NONE) {
552 g_mutex_lock(&sync_mutex);
553 auto_destroy_manager = FALSE;
554 g_hash_table_remove(resource_managers, rm);
555 auto_destroy_manager = TRUE;
556 g_mutex_unlock(&sync_mutex);
557 g_print("Resource manager %p destroyed successfully\n", rm);
559 print_api_error("Resource manager couldn't be destroyed", err);
563 static void process_mark_for_acquire_cmd(gchar **cmd_tokens)
565 mm_resource_manager_error_e err;
566 mm_resource_manager_h rm;
567 mm_resource_manager_res_h res_h;
568 mm_resource_manager_res_volume volume;
571 rm = get_manager_from_cmd(cmd_tokens);
575 if (!get_resource_type_from_cmd(cmd_tokens, &resource))
578 if (!get_volume_from_cmd(cmd_tokens, &volume))
581 err = mm_resource_manager_mark_for_acquire(rm, resource, volume, &res_h);
582 if (err == MM_RESOURCE_MANAGER_ERROR_NONE) {
583 const char *res_name = GET_ENUM_STR(resource, resource_str);
585 g_mutex_lock(&sync_mutex);
586 g_hash_table_insert(g_hash_table_lookup(resource_managers, rm),
587 res_h, g_new0(mm_resource_manager_res_state_e, 1));
588 g_mutex_unlock(&sync_mutex);
590 g_print("Resource '%s' of volume %d is marked for acquire in RM %p successfully\n",
591 res_name, volume, rm);
593 print_api_error("Resource couldn't be marked for acquire", err);
597 static void process_mark_for_release_cmd(gchar **cmd_tokens)
599 mm_resource_manager_error_e err;
600 mm_resource_manager_h rm;
601 mm_resource_manager_res_h resource;
602 mm_resource_manager_res_state_e *state_p;
603 GHashTable *resources;
605 rm = get_manager_from_cmd(cmd_tokens);
609 resource = get_resource_from_cmd(cmd_tokens, rm);
613 g_mutex_lock(&sync_mutex);
614 resources = g_hash_table_lookup(resource_managers, rm);
615 state_p = (mm_resource_manager_res_state_e *)g_hash_table_lookup(resources, resource);
616 err = mm_resource_manager_mark_for_release(rm, resource);
617 if (err == MM_RESOURCE_MANAGER_ERROR_NONE) {
619 if (*state_p == MM_RESOURCE_MANAGER_RES_STATE_FOR_ACQUIRE)
620 g_hash_table_remove(resources, resource);
622 *state_p = MM_RESOURCE_MANAGER_RES_STATE_FOR_RELEASE;
624 g_print("Resource handle %p is marked for release in RM %p successfully\n",
627 print_api_error("Resource manager couldn't mark resource for release", err);
629 g_mutex_unlock(&sync_mutex);
632 static gboolean is_marked_for_acquire(gpointer resource, gpointer state, gpointer user_data)
634 return *((mm_resource_manager_res_state_e *)state) == MM_RESOURCE_MANAGER_RES_STATE_FOR_ACQUIRE;
637 static void mark_all_for_release(gpointer resource, gpointer state, gpointer user_data)
639 mm_resource_manager_res_state_e *state_p = (mm_resource_manager_res_state_e *)state;
640 if (*state_p == MM_RESOURCE_MANAGER_RES_STATE_ACQUIRED)
641 *state_p = MM_RESOURCE_MANAGER_RES_STATE_FOR_RELEASE;
644 static void process_mark_for_release_all_cmd(gchar **cmd_tokens)
646 mm_resource_manager_error_e err;
647 mm_resource_manager_h rm;
648 GHashTable *resources;
650 rm = get_manager_from_cmd(cmd_tokens);
654 err = mm_resource_manager_mark_all_for_release(rm);
655 if (err == MM_RESOURCE_MANAGER_ERROR_NONE) {
657 g_mutex_lock(&sync_mutex);
658 resources = g_hash_table_lookup(resource_managers, rm);
659 g_hash_table_foreach(resources, mark_all_for_release, NULL);
660 g_hash_table_foreach_remove(resources, is_marked_for_acquire, NULL);
661 g_mutex_unlock(&sync_mutex);
663 g_print("All resources are marked for release in RM %p successfully\n", rm);
665 print_api_error("Resource manager couldn't mark resources for release", err);
669 static void process_resize_marked_cmd(gchar **cmd_tokens)
671 mm_resource_manager_error_e err;
672 mm_resource_manager_h rm;
673 mm_resource_manager_res_h res_h;
674 mm_resource_manager_res_volume volume;
675 mm_resource_manager_res_state_e *state;
677 rm = get_manager_from_cmd(cmd_tokens);
681 res_h = get_resource_from_cmd(cmd_tokens, rm);
685 if (!get_volume_from_cmd(cmd_tokens, &volume))
688 err = mm_resource_manager_resize_marked(rm, res_h, volume);
689 if (err == MM_RESOURCE_MANAGER_ERROR_NONE) {
691 g_mutex_lock(&sync_mutex);
692 state = (mm_resource_manager_res_state_e *)g_hash_table_lookup(
693 g_hash_table_lookup(resource_managers, rm), res_h);
694 *state = MM_RESOURCE_MANAGER_RES_STATE_FOR_ACQUIRE;
695 g_mutex_unlock(&sync_mutex);
697 g_print("Resource handle %p is resized to volume %d and marked "
698 "for acquire in RM %p successfully\n", res_h, volume, rm);
700 print_api_error("Resource couldn't be marked for acquire", err);
704 static void move_to_acquired(gpointer resource, gpointer state,
707 mm_resource_manager_res_state_e *res_state =
708 (mm_resource_manager_res_state_e *)state;
709 if (*res_state == MM_RESOURCE_MANAGER_RES_STATE_FOR_ACQUIRE)
710 *res_state = MM_RESOURCE_MANAGER_RES_STATE_ACQUIRED;
713 static gboolean is_marked_for_release(gpointer resource, gpointer state,
716 return *((mm_resource_manager_res_state_e *)state) ==
717 MM_RESOURCE_MANAGER_RES_STATE_FOR_RELEASE;
720 static void process_commit_cmd(gchar **cmd_tokens)
722 mm_resource_manager_error_e err;
723 mm_resource_manager_h rm;
724 GHashTable *resources;
726 rm = get_manager_from_cmd(cmd_tokens);
730 err = mm_resource_manager_commit(rm);
732 case MM_RESOURCE_MANAGER_ERROR_NONE:
733 g_mutex_lock(&sync_mutex);
734 resources = g_hash_table_lookup(resource_managers, rm);
735 g_hash_table_foreach(resources, move_to_acquired, NULL);
736 g_hash_table_foreach_remove(resources, is_marked_for_release, NULL);
737 g_mutex_unlock(&sync_mutex);
739 g_print("Changes in RM %p were committed successfully\n", rm);
741 case MM_RESOURCE_MANAGER_ERROR_LOW_PRIORITY:
742 print_api_error("Commit couldn't be done because of resource conflict", err);
745 print_api_error("Commit couldn't be done", err);
750 static void process_app_class_list_cmd(gchar **cmd_tokens)
752 display_app_classes();
755 static void process_resource_type_list_cmd(gchar **cmd_tokens)
757 display_resource_types(cmd_tokens);
760 static void process_resource_type_condition_list_cmd(gchar **cmd_tokens)
762 display_conditions(cmd_tokens);
765 static void process_status_cmd(gchar **cmd_tokens)
767 display_manager_list();
770 static gboolean input(GIOChannel *channel)
773 GError *error = NULL;
777 cmd_line = g_string_new(NULL);
778 if (g_io_channel_read_line_string(channel, cmd_line, &read_size, &error) != G_IO_STATUS_NORMAL)
781 g_strstrip(cmd_line->str);
783 if (g_strcmp0(cmd_line->str, "q") == 0) {
784 g_string_free(cmd_line, TRUE);
785 g_main_loop_quit(loop);
789 cmd_tokens = g_strsplit(cmd_line->str, " ", 0);
792 g_string_free(cmd_line, TRUE);
793 g_print("Empty command\n");
799 if (!cmd_tokens[0]) {
800 g_string_free(cmd_line, TRUE);
801 g_print("Empty command\n");
802 g_strfreev(cmd_tokens);
808 switch (cmd_tokens[0][0]) {
809 case TEST_COMMAND_CREATE:
810 process_create_cmd(cmd_tokens);
812 case TEST_COMMAND_DESTROY:
813 process_destroy_cmd(cmd_tokens);
815 case TEST_COMMAND_MARK_ACQUIRE:
816 process_mark_for_acquire_cmd(cmd_tokens);
818 case TEST_COMMAND_MARK_RELEASE:
819 process_mark_for_release_cmd(cmd_tokens);
821 case TEST_COMMAND_MARK_RELEASE_ALL:
822 process_mark_for_release_all_cmd(cmd_tokens);
824 case TEST_COMMAND_MARK_RESIZE:
825 process_resize_marked_cmd(cmd_tokens);
827 case TEST_COMMAND_COMMIT:
828 process_commit_cmd(cmd_tokens);
830 case TEST_COMMAND_APP_CLASS_LIST:
831 process_app_class_list_cmd(cmd_tokens);
833 case TEST_COMMAND_RES_TYPE_LIST:
834 process_resource_type_list_cmd(cmd_tokens);
836 case TEST_COMMAND_RES_TYPE_COND_LIST:
837 process_resource_type_condition_list_cmd(cmd_tokens);
839 case TEST_COMMAND_STATUS:
840 process_status_cmd(cmd_tokens);
843 g_print("Invalid command\n");
846 g_string_free(cmd_line, TRUE);
847 g_strfreev(cmd_tokens);
851 return input(channel);
854 static void free_resource_manager(void *rm)
856 if (auto_destroy_manager)
857 mm_resource_manager_destroy(rm);
860 static void free_resources(void *rs)
862 g_hash_table_destroy((GHashTable*)rs);
865 static gboolean check_const_string_arrays()
869 for (i = 0; resource_str[i]; i++);
870 if (i != MM_RESOURCE_MANAGER_RES_TYPE_MAX)
873 for (i = 0; app_class_str[i]; i++);
874 if (i != MM_RESOURCE_MANAGER_APP_CLASS_MAX)
877 for (i = 0; status_str[i]; i++);
878 if (i != MM_RESOURCE_MANAGER_STATUS_MAX)
881 for (i = 0; condition_str[i]; i++);
882 if (i != MM_RESOURCE_MANAGER_RES_TYPE_COND_MAX)
888 int main(int argc, char *argv[])
890 GIOChannel *stdin_channel;
893 if (!check_const_string_arrays()) {
894 g_print("FATAL ERROR: Resource manager API was changed. The test suite must be changed too.\n");
898 while ((option = getopt(argc, argv, "?hs")) != -1) {
902 g_print("Usage: %s [-s]\n s - don't display menu\n ?,h - usage\n", argv[0]);
910 loop = g_main_loop_new(NULL, 0);
911 stdin_channel = g_io_channel_unix_new(fileno(stdin));
912 g_io_channel_set_flags(stdin_channel, G_IO_FLAG_NONBLOCK, NULL);
913 g_io_add_watch(stdin_channel, G_IO_IN, (GIOFunc) input, NULL);
915 resource_managers = g_hash_table_new_full(NULL, NULL, free_resource_manager, free_resources);
919 g_main_loop_run(loop);
920 g_hash_table_destroy(resource_managers);
921 g_main_loop_unref(loop);