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 "
153 "cb call. Nothing is done.", rm);
155 g_mutex_unlock(&sync_mutex);
159 static void status_cb(mm_resource_manager_h rm, mm_resource_manager_status_e status,
162 g_print("Status cb of resource manager %p is called with status %d (%s)\n",
163 rm, status, status_str[status]);
165 g_mutex_lock(&sync_mutex);
166 if (g_hash_table_lookup(resource_managers, rm)) {
169 case MM_RESOURCE_MANAGER_STATUS_DISCONNECTED:
170 g_print("Resource manager %p cannot be used anymore and must be"
171 " destroyed.\n", rm);
177 g_print("WARNING: resource manager %p was removed during the status "
180 g_mutex_unlock(&sync_mutex);
183 static int get_max_str_len(const char *strs[])
189 for (i = 0; strs[i]; i++) {
190 len = strlen(strs[i]);
198 static int counter(gboolean reset)
200 static int counter = 1;
209 static void display_menu_head(gchar *title)
214 for (i = 0; i < MAX_CMD_LINE_LEN; i++)
216 g_print("\n %s\n", title);
217 for (i = 0; i < MAX_CMD_LINE_LEN; i++)
222 static void display_menu_tail(gboolean input)
226 for (i = 0; i < MAX_CMD_LINE_LEN; i++)
229 for (i = 0; i < MAX_CMD_LINE_LEN; i++)
236 static void display_app_classes()
240 display_menu_head("Application Classes");
242 for (i = 0; i < MM_RESOURCE_MANAGER_APP_CLASS_MAX; i++)
243 g_print("%d - %s\n", i, app_class_str[i]);
245 display_menu_tail(FALSE);
248 static gpointer get_manager_by_index(int i)
254 mans = g_hash_table_get_keys_as_array(resource_managers, &len);
256 man = i < len ? mans[i] : NULL;
263 static mm_resource_manager_h get_manager_from_cmd(gchar **cmd_tokens)
265 mm_resource_manager_h rm;
268 if (!cmd_tokens[1]) {
269 print_error("Resource manager number was not specified");
273 manager_i = g_ascii_strtoull(cmd_tokens[1], NULL, 10);
274 if (!manager_i && g_strcmp0(cmd_tokens[1], "0")) {
275 print_error("Resource manager number is not unsigned integer");
279 rm = get_manager_by_index(manager_i - 1);
281 print_error("Resource manager number is out of bounds");
288 static void display_resource_types(gchar **cmd_tokens)
291 mm_resource_manager_res_volume volume;
292 mm_resource_manager_h rm;
293 static int max_res_len = 0;
296 max_res_len = get_max_str_len(resource_str);
298 rm = get_manager_from_cmd(cmd_tokens);
302 display_menu_head("Resource Types (Max Volume)");
304 for (i = 0; i < MM_RESOURCE_MANAGER_RES_TYPE_MAX; i++) {
305 mm_resource_manager_get_res_type_max_volume(rm, i, &volume);
306 g_print("%d - %*s %d\n", i, max_res_len, resource_str[i], volume);
309 display_menu_tail(FALSE);
312 static void display_conditions(gchar **cmd_tokens)
316 mm_resource_manager_res_volume volume;
317 static int max_cond_width = 0;
318 static int max_res_width = 0;
319 mm_resource_manager_h rm;
321 rm = get_manager_from_cmd(cmd_tokens);
325 if (!max_cond_width) {
326 max_res_width = get_max_str_len(resource_str);
327 align = (MAX_CMD_LINE_LEN - max_res_width) /
328 MM_RESOURCE_MANAGER_RES_TYPE_COND_MAX;
329 max_cond_width = get_max_str_len(condition_str);
330 if (align > max_cond_width)
331 max_cond_width = align;
334 display_menu_head("Resource Conditions");
336 g_print("%*s", max_res_width, "type/cond");
337 for (j = 0; j < MM_RESOURCE_MANAGER_RES_TYPE_COND_MAX; j++)
338 g_print("%*s", max_cond_width, condition_str[j]);
342 for (i = 0; i < MM_RESOURCE_MANAGER_RES_TYPE_MAX; i++) {
343 g_print("%*s", max_res_width, resource_str[i]);
344 for (j = 0; j < MM_RESOURCE_MANAGER_RES_TYPE_COND_MAX; j++) {
345 if (mm_resource_manager_get_res_type_volume(rm, i, j, &volume) ==
346 MM_RESOURCE_MANAGER_ERROR_NONE)
347 g_print("%*d", max_cond_width, volume);
349 g_print("%*s", max_cond_width, "-");
354 display_menu_tail(FALSE);
357 static void display_manager_resource(gpointer resource, gpointer state,
360 mm_resource_manager_h rm = user_data;
361 mm_resource_manager_res_h res = resource;
362 mm_resource_manager_res_info_s res_info;
364 g_print("%*d.%*s", INDENT, counter(FALSE), INDENT, " ");
365 if (mm_resource_manager_get_resource_info(rm, res, &res_info) ==
366 MM_RESOURCE_MANAGER_ERROR_NONE) {
367 g_print("%p %s (%s, %d, %s)\n", res,
368 GET_ENUM_STR(*((mm_resource_manager_res_state_e*)state), res_state_str),
369 GET_ENUM_STR(res_info.type, resource_str),
370 res_info.volume, res_info.is_acquire_failed ? "TRUE" : "FALSE");
372 g_print("(!) Can't get resource info\n");
376 static void display_manager(gpointer manager, gpointer resources, gpointer user_data)
378 int *number_p = user_data;
380 if (g_hash_table_size(resources)) {
381 g_print("%d. manager %p resources:\n", (*number_p)++, manager);
383 g_hash_table_foreach(resources, display_manager_resource, manager);
385 g_print("%d. manager %p\n", (*number_p)++, manager);
389 static void display_manager_list()
393 display_menu_head("Existing Resource Managers");
394 g_mutex_lock(&sync_mutex);
395 g_hash_table_foreach(resource_managers, display_manager, &number);
396 g_mutex_unlock(&sync_mutex);
397 display_menu_tail(FALSE);
400 static void display_menu()
405 display_menu_head("MM Resource Manager Test Suite: Main menu");
408 * <app class> - int value of mm_resource_manager_app_class_e
409 * <manager number> - number returned by the status command
410 * <numeric resource type> - int value of mm_resource_manager_res_type_e
411 * <volume> - int value; -1 means full volume of resource
412 * <resource number> - number returned by the status command
414 g_print("c - Create Resource Manager <app class>\n");
415 g_print("d - Destroy Resource Manager <manager number>\n");
416 g_print("a - Mark For Acquire <manager number> <numeric resource type> <volume>\n");
417 g_print("r - Mark For Release <manager number> <resource number>\n");
418 g_print("R - Mark All For Release <manager number>\n");
419 g_print("s - Resize Marked <manager number> <resource number> <volume>\n");
420 g_print("m - Commit <manager number>\n");
421 g_print("p - Print Application Classes\n");
422 g_print("t - Print Resource Types <manager number>\n");
423 g_print("n - Print Resource Conditions <manager number>\n");
424 g_print("u - Print Resource Manager List and Status\n");
425 g_print("q - Quit\n");
427 display_menu_tail(TRUE);
430 static gpointer get_resource_by_index(mm_resource_manager_h rm, int i)
436 reses = g_hash_table_get_keys_as_array(
437 g_hash_table_lookup(resource_managers, rm), &len);
439 res = i < len ? reses[i] : NULL;
446 static mm_resource_manager_res_h get_resource_from_cmd(gchar **cmd_tokens,
447 mm_resource_manager_h rm)
449 mm_resource_manager_res_h res;
452 if (!cmd_tokens[2]) {
453 print_error("Resource number was not specified");
457 res_i = g_ascii_strtoull(cmd_tokens[2], NULL, 10);
458 if (!res_i && g_strcmp0(cmd_tokens[2], "0")) {
459 print_error("Resource number is not unsigned integer");
463 res = get_resource_by_index(rm, res_i - 1);
465 print_error("Resource number is out of bounds");
472 static gboolean get_resource_type_from_cmd(gchar **cmd_tokens, int *res_p)
474 if (!cmd_tokens[2]) {
475 print_error("Resource was not specified");
479 *res_p = g_ascii_strtoull(cmd_tokens[2], NULL, 10);
480 if (!*res_p && g_strcmp0(cmd_tokens[2], "0")) {
481 print_error("Resource is not integer");
488 static gboolean get_volume_from_cmd(gchar **cmd_tokens, int *res_p)
490 if (!cmd_tokens[3]) {
491 print_error("Resource volume was not specified");
495 *res_p = g_ascii_strtoull(cmd_tokens[3], NULL, 10);
496 if (!*res_p && g_strcmp0(cmd_tokens[3], "0")) {
497 print_error("Resource volume is not integer");
504 static void free_resource_state(void *res_state_p)
509 static void process_create_cmd(gchar **cmd_tokens)
512 mm_resource_manager_error_e err;
513 mm_resource_manager_h rm;
515 if (!cmd_tokens[1]) {
516 print_error("Application class was not specified");
520 app_class = g_ascii_strtoull(cmd_tokens[1], NULL, 10);
521 if (!app_class && g_strcmp0(cmd_tokens[1], "0")) {
522 print_error("Application class is not unsigned integer");
526 err = mm_resource_manager_create(app_class, release_cb, NULL, &rm);
527 if (err == MM_RESOURCE_MANAGER_ERROR_NONE) {
528 if (mm_resource_manager_set_status_cb(rm, status_cb, NULL) ==
529 MM_RESOURCE_MANAGER_ERROR_NONE) {
530 g_mutex_lock(&sync_mutex);
531 g_hash_table_insert(resource_managers, rm,
532 g_hash_table_new_full(NULL, NULL, NULL, free_resource_state));
533 g_mutex_unlock(&sync_mutex);
534 g_print("Resource manager %p of class '%s' created successfully\n",
535 rm, GET_ENUM_STR(app_class, app_class_str));
537 mm_resource_manager_destroy(rm);
538 print_api_error("Resource manager couldn't be created. "
539 "Could not set callbacks", err);
542 print_api_error("Resource manager couldn't be created", err);
546 static void process_destroy_cmd(gchar **cmd_tokens)
548 mm_resource_manager_error_e err;
549 mm_resource_manager_h rm;
551 rm = get_manager_from_cmd(cmd_tokens);
555 err = mm_resource_manager_destroy(rm);
556 if (err == MM_RESOURCE_MANAGER_ERROR_NONE) {
557 g_mutex_lock(&sync_mutex);
558 auto_destroy_manager = FALSE;
559 g_hash_table_remove(resource_managers, rm);
560 auto_destroy_manager = TRUE;
561 g_mutex_unlock(&sync_mutex);
562 g_print("Resource manager %p destroyed successfully\n", rm);
564 print_api_error("Resource manager couldn't be destroyed", err);
568 static void process_mark_for_acquire_cmd(gchar **cmd_tokens)
570 mm_resource_manager_error_e err;
571 mm_resource_manager_h rm;
572 mm_resource_manager_res_h res_h;
573 mm_resource_manager_res_volume volume;
576 rm = get_manager_from_cmd(cmd_tokens);
580 if (!get_resource_type_from_cmd(cmd_tokens, &resource))
583 if (!get_volume_from_cmd(cmd_tokens, &volume))
586 err = mm_resource_manager_mark_for_acquire(rm, resource, volume, &res_h);
587 if (err == MM_RESOURCE_MANAGER_ERROR_NONE) {
588 const char *res_name = GET_ENUM_STR(resource, resource_str);
590 g_mutex_lock(&sync_mutex);
591 g_hash_table_insert(g_hash_table_lookup(resource_managers, rm),
592 res_h, g_new0(mm_resource_manager_res_state_e, 1));
593 g_mutex_unlock(&sync_mutex);
595 g_print("Resource '%s' of volume %d is marked for acquire in RM %p successfully\n",
596 res_name, volume, rm);
598 print_api_error("Resource couldn't be marked for acquire", err);
602 static void process_mark_for_release_cmd(gchar **cmd_tokens)
604 mm_resource_manager_error_e err;
605 mm_resource_manager_h rm;
606 mm_resource_manager_res_h resource;
607 mm_resource_manager_res_state_e *state_p;
608 GHashTable *resources;
610 rm = get_manager_from_cmd(cmd_tokens);
614 resource = get_resource_from_cmd(cmd_tokens, rm);
618 g_mutex_lock(&sync_mutex);
619 resources = g_hash_table_lookup(resource_managers, rm);
620 state_p = (mm_resource_manager_res_state_e *)g_hash_table_lookup(
621 resources, resource);
622 err = mm_resource_manager_mark_for_release(rm, resource);
623 if (err == MM_RESOURCE_MANAGER_ERROR_NONE) {
625 if (*state_p == MM_RESOURCE_MANAGER_RES_STATE_FOR_ACQUIRE)
626 g_hash_table_remove(resources, resource);
628 *state_p = MM_RESOURCE_MANAGER_RES_STATE_FOR_RELEASE;
630 g_print("Resource handle %p is marked for release in RM %p successfully\n",
633 print_api_error("Resource manager couldn't mark resource for release", err);
635 g_mutex_unlock(&sync_mutex);
638 static gboolean is_marked_for_acquire(gpointer resource, gpointer state,
641 return *((mm_resource_manager_res_state_e *)state) ==
642 MM_RESOURCE_MANAGER_RES_STATE_FOR_ACQUIRE;
645 static void mark_all_for_release(gpointer resource, gpointer state, gpointer
648 mm_resource_manager_res_state_e *state_p =
649 (mm_resource_manager_res_state_e *)state;
650 if (*state_p == MM_RESOURCE_MANAGER_RES_STATE_ACQUIRED)
651 *state_p = MM_RESOURCE_MANAGER_RES_STATE_FOR_RELEASE;
654 static void process_mark_for_release_all_cmd(gchar **cmd_tokens)
656 mm_resource_manager_error_e err;
657 mm_resource_manager_h rm;
658 GHashTable *resources;
660 rm = get_manager_from_cmd(cmd_tokens);
664 err = mm_resource_manager_mark_all_for_release(rm);
665 if (err == MM_RESOURCE_MANAGER_ERROR_NONE) {
667 g_mutex_lock(&sync_mutex);
668 resources = g_hash_table_lookup(resource_managers, rm);
669 g_hash_table_foreach(resources, mark_all_for_release, NULL);
670 g_hash_table_foreach_remove(resources, is_marked_for_acquire, NULL);
671 g_mutex_unlock(&sync_mutex);
673 g_print("All resources are marked for release in RM %p successfully\n", rm);
675 print_api_error("Resource manager couldn't mark resources for release", err);
679 static void process_resize_marked_cmd(gchar **cmd_tokens)
681 mm_resource_manager_error_e err;
682 mm_resource_manager_h rm;
683 mm_resource_manager_res_h res_h;
684 mm_resource_manager_res_volume volume;
685 mm_resource_manager_res_state_e *state;
687 rm = get_manager_from_cmd(cmd_tokens);
691 res_h = get_resource_from_cmd(cmd_tokens, rm);
695 if (!get_volume_from_cmd(cmd_tokens, &volume))
698 err = mm_resource_manager_resize_marked(rm, res_h, volume);
699 if (err == MM_RESOURCE_MANAGER_ERROR_NONE) {
701 g_mutex_lock(&sync_mutex);
702 state = (mm_resource_manager_res_state_e *)g_hash_table_lookup(
703 g_hash_table_lookup(resource_managers, rm), res_h);
704 *state = MM_RESOURCE_MANAGER_RES_STATE_FOR_ACQUIRE;
705 g_mutex_unlock(&sync_mutex);
707 g_print("Resource handle %p is resized to volume %d and marked "
708 "for acquire in RM %p successfully\n", res_h, volume, rm);
710 print_api_error("Resource couldn't be marked for acquire", err);
714 static void move_to_acquired(gpointer resource, gpointer state,
717 mm_resource_manager_res_state_e *res_state =
718 (mm_resource_manager_res_state_e *)state;
719 if (*res_state == MM_RESOURCE_MANAGER_RES_STATE_FOR_ACQUIRE)
720 *res_state = MM_RESOURCE_MANAGER_RES_STATE_ACQUIRED;
723 static gboolean is_marked_for_release(gpointer resource, gpointer state,
726 return *((mm_resource_manager_res_state_e *)state) ==
727 MM_RESOURCE_MANAGER_RES_STATE_FOR_RELEASE;
730 static void process_commit_cmd(gchar **cmd_tokens)
732 mm_resource_manager_error_e err;
733 mm_resource_manager_h rm;
734 GHashTable *resources;
736 rm = get_manager_from_cmd(cmd_tokens);
740 err = mm_resource_manager_commit(rm);
742 case MM_RESOURCE_MANAGER_ERROR_NONE:
743 g_mutex_lock(&sync_mutex);
744 resources = g_hash_table_lookup(resource_managers, rm);
745 g_hash_table_foreach(resources, move_to_acquired, NULL);
746 g_hash_table_foreach_remove(resources, is_marked_for_release, NULL);
747 g_mutex_unlock(&sync_mutex);
749 g_print("Changes in RM %p were committed successfully\n", rm);
751 case MM_RESOURCE_MANAGER_ERROR_LOW_PRIORITY:
752 print_api_error("Commit couldn't be done because of resource conflict",
756 print_api_error("Commit couldn't be done", err);
761 static void process_app_class_list_cmd(gchar **cmd_tokens)
763 display_app_classes();
766 static void process_resource_type_list_cmd(gchar **cmd_tokens)
768 display_resource_types(cmd_tokens);
771 static void process_resource_type_condition_list_cmd(gchar **cmd_tokens)
773 display_conditions(cmd_tokens);
776 static void process_status_cmd(gchar **cmd_tokens)
778 display_manager_list();
781 static gboolean input(GIOChannel *channel)
784 GError *error = NULL;
788 cmd_line = g_string_new(NULL);
789 if (g_io_channel_read_line_string(channel, cmd_line, &read_size, &error) !=
793 g_strstrip(cmd_line->str);
795 if (g_strcmp0(cmd_line->str, "q") == 0) {
796 g_string_free(cmd_line, TRUE);
797 g_main_loop_quit(loop);
801 cmd_tokens = g_strsplit(cmd_line->str, " ", 0);
804 g_string_free(cmd_line, TRUE);
805 g_print("Empty command\n");
811 if (!cmd_tokens[0]) {
812 g_string_free(cmd_line, TRUE);
813 g_print("Empty command\n");
814 g_strfreev(cmd_tokens);
820 switch (cmd_tokens[0][0]) {
821 case TEST_COMMAND_CREATE:
822 process_create_cmd(cmd_tokens);
824 case TEST_COMMAND_DESTROY:
825 process_destroy_cmd(cmd_tokens);
827 case TEST_COMMAND_MARK_ACQUIRE:
828 process_mark_for_acquire_cmd(cmd_tokens);
830 case TEST_COMMAND_MARK_RELEASE:
831 process_mark_for_release_cmd(cmd_tokens);
833 case TEST_COMMAND_MARK_RELEASE_ALL:
834 process_mark_for_release_all_cmd(cmd_tokens);
836 case TEST_COMMAND_MARK_RESIZE:
837 process_resize_marked_cmd(cmd_tokens);
839 case TEST_COMMAND_COMMIT:
840 process_commit_cmd(cmd_tokens);
842 case TEST_COMMAND_APP_CLASS_LIST:
843 process_app_class_list_cmd(cmd_tokens);
845 case TEST_COMMAND_RES_TYPE_LIST:
846 process_resource_type_list_cmd(cmd_tokens);
848 case TEST_COMMAND_RES_TYPE_COND_LIST:
849 process_resource_type_condition_list_cmd(cmd_tokens);
851 case TEST_COMMAND_STATUS:
852 process_status_cmd(cmd_tokens);
855 g_print("Invalid command\n");
858 g_string_free(cmd_line, TRUE);
859 g_strfreev(cmd_tokens);
863 return input(channel);
866 static void free_resource_manager(void *rm)
868 if (auto_destroy_manager)
869 mm_resource_manager_destroy(rm);
872 static void free_resources(void *rs)
874 g_hash_table_destroy((GHashTable*)rs);
877 static gboolean check_const_string_arrays()
881 for (i = 0; resource_str[i]; i++);
882 if (i != MM_RESOURCE_MANAGER_RES_TYPE_MAX)
885 for (i = 0; app_class_str[i]; i++);
886 if (i != MM_RESOURCE_MANAGER_APP_CLASS_MAX)
889 for (i = 0; status_str[i]; i++);
890 if (i != MM_RESOURCE_MANAGER_STATUS_MAX)
893 for (i = 0; condition_str[i]; i++);
894 if (i != MM_RESOURCE_MANAGER_RES_TYPE_COND_MAX)
900 int main(int argc, char *argv[])
902 GIOChannel *stdin_channel;
905 if (!check_const_string_arrays()) {
906 g_print("FATAL ERROR: Resource manager API was changed. "
907 "The test suite must be changed too.\n");
911 while ((option = getopt(argc, argv, "?hs")) != -1) {
915 g_print("Usage: %s [-s]\n"
916 " s - don't display menu\n"
917 " ?,h - usage\n", argv[0]);
925 loop = g_main_loop_new(NULL, 0);
926 stdin_channel = g_io_channel_unix_new(fileno(stdin));
927 g_io_channel_set_flags(stdin_channel, G_IO_FLAG_NONBLOCK, NULL);
928 g_io_add_watch(stdin_channel, G_IO_IN, (GIOFunc) input, NULL);
930 resource_managers = g_hash_table_new_full(NULL, NULL,
931 free_resource_manager, free_resources);
935 g_main_loop_run(loop);
936 g_hash_table_destroy(resource_managers);
937 g_main_loop_unref(loop);