From: Youngjae Cho Date: Tue, 25 Jul 2023 11:21:10 +0000 (+0900) Subject: libcommon: Introduce notifier X-Git-Tag: accepted/tizen/unified/20230731.175325~4 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=refs%2Fchanges%2F59%2F296359%2F2;p=platform%2Fcore%2Fsystem%2Flibsyscommon.git libcommon: Introduce notifier The libsyscommon notifer provides mean that communicate between different modules. And it works based on publish-subscribe pattern. If someone wants to listen to an event, it subscribes to notify id that is defined by event publisher, using subscribe function such as - syscommon_notifier_subscribe_notify_priority() - syscommon_notifier_subscribe_notify() - syscommon_notifier_subscribe_notify_udata_priority() - syscommon_notifier_subscribe_notify_udata() Obviously, it is possible to unsubscribe notify via - syscommon_notifier_unsubscribe_notify() - syscommon_notifier_unsubscribe_notify_udata() If someone want publish a notify, it can be done by the functions such as - syscommon_notifier_emit_notify() - syscommon_notifier_emit_notify_once() See below for a detailed description about libsyscommon notifier. int syscommon_notifier_subscribe_notify_priority() - Subscribe notify without user_data callback. - Higher number of priority will be notified first. int syscommon_notifier_subscribe_notify() - Subscribe notify without user_data callback - Automatically assign default priority of 0. int syscommon_notifier_unsubscribe_notify() - Unsubscribe notify callback without user_data. int syscommon_notifier_subscribe_notify_udata_priority() - Subscribe notify with user_data callback. - Provide destroy callback to free user_data on unsubscribing. - Higher number of priority will be notified first. - Return notify id and can be used for unsubscribing. int syscommon_notifier_unsubscribe_notify_udata() - Subscribe notify with user_data callback - Provide destroy callback to free user_data on unsubscribing - Automatically assign default priority of 0. - Return notify id and can be used for unsubscribing. int syscommon_notifier_subscribe_notify_udata() - Unsubscribe notify callback with user_data. - Invoke destroy function with user_data. void syscommon_notifier_emit_notify() - Emit notify. void syscommon_notifier_emit_notify_once() - Emit notify only once. - Notification after the first one is ignored. Change-Id: I1853f5a51e999c1f20b34c9281becb9cfbdb8a8b Signed-off-by: Youngjae Cho Change-Id: Iff113c8869e27a90f11156181b500d25893387a8 --- diff --git a/CMakeLists.txt b/CMakeLists.txt index 9094e74..f708755 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -23,6 +23,7 @@ SET(libsyscommon_SRCS src/libcommon/common.c src/libcommon/bitmap.c src/libcommon/proc.c + src/libcommon/notifier.c src/resource-manager/resource-manager.c src/resource-manager/resource-device.c src/resource-manager/resource-listener-epoll.c diff --git a/include/libsyscommon/notifier.h b/include/libsyscommon/notifier.h new file mode 100644 index 0000000..f88d22f --- /dev/null +++ b/include/libsyscommon/notifier.h @@ -0,0 +1,77 @@ +/* MIT License + * + * Copyright (c) 2023 Samsung Electronics Co., Ltd. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. */ + +#ifndef __SYSCOMMON_NOTIFIER_H__ +#define __SYSCOMMON_NOTIFIER_H__ + +typedef int (*syscommon_notifier_cb) (void *notify_data); +typedef int (*syscommon_notifier_udata_cb) (void *notify_data, void *user_data); +typedef void (*syscommon_notifier_destroy_cb) (void *user_data); + +/** + * Subscribe notify without user_data callback. + * Higher number of priority will be notified first. + */ +int syscommon_notifier_subscribe_notify_priority(int type, syscommon_notifier_cb func, int priority); + +/* Subscribe notify without user_data callback, default priority 0 */ +static inline int syscommon_notifier_subscribe_notify(int type, syscommon_notifier_cb func) +{ + return syscommon_notifier_subscribe_notify_priority(type, func, 0); +} + +/* Unsubscribe notify callback without user_data */ +int syscommon_notifier_unsubscribe_notify(int type, syscommon_notifier_cb func); + +/** + * Subscribe notify with user_data callback, destroy function, and priority. + * Higher number of priority will be notified first. + * Return notify id and can it be used for unsubscribing. + */ +int syscommon_notifier_subscribe_notify_udata_priority(int type, + syscommon_notifier_udata_cb func_udata, void *user_data, + syscommon_notifier_destroy_cb func_destroy_udata, int priority); + +/** + * Subscribe notify with user_data callback, and default priority 0. + * Return notify id and it can be used for unsubscribing. + */ +static inline int syscommon_notifier_subscribe_notify_udata(int type, + syscommon_notifier_udata_cb func_udata, void *user_data, syscommon_notifier_destroy_cb func_destroy) +{ + return syscommon_notifier_subscribe_notify_udata_priority(type, func_udata, user_data, func_destroy, 0); +} + +/** + * Unsubscribe notify callback with user_data. + * Invoke destroy function with user_data. + */ +int syscommon_notifier_unsubscribe_notify_udata(int id); + +/* Emit notify. */ +void syscommon_notifier_emit_notify(int type, void *notify_data); + +/* Emit notify only once. + * Notification after the first one is ignored. */ +void syscommon_notifier_emit_notify_once(int type, void *notify_data); + +#endif /* __SYSCOMMON_NOTIFIER_H__ */ diff --git a/src/libcommon/notifier.c b/src/libcommon/notifier.c new file mode 100644 index 0000000..073bfd3 --- /dev/null +++ b/src/libcommon/notifier.c @@ -0,0 +1,215 @@ +/* MIT License + * + * Copyright (c) 2023 Samsung Electronics Co., Ltd. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is furnished + * to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. */ + +#include +#include +#include +#include + +#include "libsyscommon/notifier.h" +#include "libsyscommon/list.h" +#include "shared/log.h" + +struct syscommon_notifier { + int id; + int priority; /* descending order */ + bool deleted; + + int type; + int (*func)(void *data); + + int (*func_udata)(void *data, void *user_data); + void (*destroyer)(void *user_data); + void *user_data; +}; + +static GList *syscommon_notifier_list; +static guint idl; + +#define FIND_NOTIFIER(a, b, d, e, f) \ + SYS_G_LIST_FOREACH(a, b, d) \ + if (e == d->e && f == (d->f) && !d->deleted) + +static gint compare_priority(gconstpointer a, gconstpointer b) +{ + /* descending order */ + return ((const struct syscommon_notifier *)b)->priority - ((const struct syscommon_notifier *)a)->priority + 1; +} + +int syscommon_notifier_subscribe_notify_priority(int type, syscommon_notifier_cb func, int priority) +{ + GList *n; + struct syscommon_notifier *notifier; + + _I("notifier type=%d, func=%p", type, func); + + if (!func) { + _E("Invalid func address."); + return -EINVAL; + } + + FIND_NOTIFIER(syscommon_notifier_list, n, notifier, type, func) { + _E("Function has already been registered, [%d, %p]", type, func); + return -EINVAL; + } + + notifier = calloc(1, sizeof(struct syscommon_notifier)); + if (!notifier) { + _E("Fail to malloc for %d notifier.", type); + return -ENOMEM; + } + + notifier->type = type; + notifier->priority = priority; + notifier->func = func; + + syscommon_notifier_list = g_list_insert_sorted(syscommon_notifier_list, notifier, compare_priority); + + return 0; +} + + +int syscommon_notifier_subscribe_notify_udata_priority(int type, + syscommon_notifier_udata_cb func_udata, void *user_data, + syscommon_notifier_destroy_cb func_destroy_udata, int priority) +{ + struct syscommon_notifier *notifier; + static int id = 1; + + _I("notifier type=%d, func=%p", type, func_udata); + + if (!func_udata) { + _E("Invalid func address."); + return -EINVAL; + } + + notifier = calloc(1, sizeof(struct syscommon_notifier)); + if (!notifier) { + _E("Fail to malloc for %d notifier.", type); + return -ENOMEM; + } + + notifier->id = id; + notifier->priority = priority; + notifier->type = type; + notifier->func_udata = func_udata; + notifier->user_data = user_data; + notifier->destroyer = func_destroy_udata; + + syscommon_notifier_list = g_list_insert_sorted(syscommon_notifier_list, notifier, compare_priority); + + ++id; + + return notifier->id; +} + +int syscommon_notifier_unsubscribe_notify(int type, syscommon_notifier_cb func) +{ + GList *n; + struct syscommon_notifier *notifier; + + if (!func) { + _E("Invalid func address."); + return -EINVAL; + } + + FIND_NOTIFIER(syscommon_notifier_list, n, notifier, type, func) { + _I("notifier type=%d, func=%p", type, func); + notifier->deleted = true; + } + + return 0; +} + +int syscommon_notifier_unsubscribe_notify_udata(int id) +{ + GList *n; + struct syscommon_notifier *notifier; + + SYS_G_LIST_FOREACH(syscommon_notifier_list, n, notifier) { + if (notifier->id == id) { + if (notifier->destroyer) + notifier->destroyer(notifier->user_data); + notifier->deleted = true; + } + } + + return 0; +} + +static gboolean delete_unused_notifier_cb(void *data) +{ + GList *n; + GList *next; + struct syscommon_notifier *notifier; + + SYS_G_LIST_FOREACH_SAFE(syscommon_notifier_list, n, next, notifier) { + if (notifier->deleted) { + SYS_G_LIST_REMOVE_LIST(syscommon_notifier_list, n); + free(notifier); + } + } + + idl = 0; + return G_SOURCE_REMOVE; +} + +void syscommon_notifier_emit_notify(int type, void *data) +{ + GList *n; + struct syscommon_notifier *notifier; + + SYS_G_LIST_FOREACH(syscommon_notifier_list, n, notifier) { + if (!notifier->deleted && type == notifier->type) { + if (notifier->func) + notifier->func(data); + else if (notifier->func_udata) + notifier->func_udata(data, notifier->user_data); + } + } + + if (!idl) + idl = g_idle_add(delete_unused_notifier_cb, NULL); +} + +void syscommon_notifier_emit_notify_once(int type, void *data) +{ + GList *n; + struct syscommon_notifier *notifier; + + SYS_G_LIST_FOREACH(syscommon_notifier_list, n, notifier) { + if (!notifier->deleted && type == notifier->type) { + if (notifier->func) { + notifier->func(data); + } else if (notifier->func_udata) { + notifier->func_udata(data, notifier->user_data); + if (notifier->destroyer) + notifier->destroyer(notifier->user_data); + } + + notifier->deleted = true; + } + } + + if (!idl) + idl = g_idle_add(delete_unused_notifier_cb, NULL); +} diff --git a/tests/libcommon/test-common.c b/tests/libcommon/test-common.c index 9df8e61..f34ce27 100644 --- a/tests/libcommon/test-common.c +++ b/tests/libcommon/test-common.c @@ -10,12 +10,22 @@ #include "libsyscommon/list.h" #include "libsyscommon/ini-parser.h" #include "libsyscommon/bitmap.h" +#include "libsyscommon/notifier.h" #include "../test-main.h" #include "../test-mock.h" #define MOCK_FILE_PATH "testfile" #define MOCK_FILE_LENGTH 100 +#define SYSCOMMON_NOTIFIER_1 (1) +#define SYSCOMMON_NOTIFIER_2 (2) +#define SYSCOMMON_NOTIFIER_3 (3) +#define SYSCOMMON_NOTIFIER_4 (4) +#define SYSCOMMON_NOTIFIER_5 (5) +#define SYSCOMMON_NOTIFIER_6 (6) +#define SYSCOMMON_NOTIFIER_7 (7) +#define SYSCOMMON_NOTIFIER_8 (8) + static int setup(void **state) { FILE *fp; @@ -273,6 +283,224 @@ static void test_all_bit(void **state) syscommon_bitmap_deinit_bitmap(bm); } +static int notify_callback(void *data) +{ + check_expected(data); + + return 0; +} + +static int notify_callback_udata(void *data, void *udata) +{ + check_expected(data); + check_expected(udata); + + return 0; +} + +static void destroy_callback_udata(void *udata) +{ + check_expected(udata); +} + +static void test_syscommon_notifier_emit_notify_p1(void **state) +{ + int retval; + + retval = syscommon_notifier_subscribe_notify(SYSCOMMON_NOTIFIER_1, notify_callback); + assert_int_equal(retval, 0); + expect_value(notify_callback, data, (void *)(intptr_t) 0x3f3f3f3f); + + syscommon_notifier_emit_notify(SYSCOMMON_NOTIFIER_1, (void *)(intptr_t) 0x3f3f3f3f); +} + +static void test_syscommon_notifier_emit_notify_p2(void **state) +{ + int retval; + int notify_data; + const int udata2 = 0xaeaeaeae; + const int udata3 = 0x99997777; + + notify_data = 0x12456321; + + /* 1st notifier */ + retval = syscommon_notifier_subscribe_notify(SYSCOMMON_NOTIFIER_2, notify_callback); + assert_int_equal(retval, 0); + + /* 2nd notifier */ + retval = syscommon_notifier_subscribe_notify_udata(SYSCOMMON_NOTIFIER_2, notify_callback_udata, (void *)(intptr_t) udata2, NULL); + assert_in_range(retval, 1, INT_MAX); + + /* expect invocation of 1st callback and check parameter */ + expect_value(notify_callback, data, (void *)(intptr_t) notify_data); + /* expect invocation of 2nd callback and check parameter */ + expect_value(notify_callback_udata, data, (void *)(intptr_t) notify_data); + expect_value(notify_callback_udata, udata,(void *)(intptr_t) udata2); + + syscommon_notifier_emit_notify(SYSCOMMON_NOTIFIER_2, (void *)(intptr_t) notify_data); + + notify_data = 0x888899dd; + + /* 3rd notifier */ + retval = syscommon_notifier_subscribe_notify_udata(SYSCOMMON_NOTIFIER_2, notify_callback_udata, (void *)(intptr_t) udata3, NULL); + assert_in_range(retval, 1, INT_MAX); + + /* expect invocation of 1st callback and check parameter */ + expect_value(notify_callback, data, (void *)(intptr_t) notify_data); + /* expect invocation of 2nd callback and check parameter */ + expect_value(notify_callback_udata, data, (void *)(intptr_t) notify_data); + expect_value(notify_callback_udata, udata, (void *)(intptr_t) udata2); + /* expect invocation of 3rd callback and check parameter */ + expect_value(notify_callback_udata, data, (void *)(intptr_t) notify_data); + expect_value(notify_callback_udata, udata, (void *)(intptr_t) udata3); + + syscommon_notifier_emit_notify(SYSCOMMON_NOTIFIER_2, (void *)(intptr_t) notify_data); +} + +static void test_syscommon_notifier_emit_notify_p3(void **state) +{ + int notify_data; + int id1, id2; + const int udata1 = 0x41a41a41; + const int udata2 = 0x77777777; + + /* first run */ + notify_data = 0x8575ddff; + + /* 1st notifier */ + id1 = syscommon_notifier_subscribe_notify_udata(SYSCOMMON_NOTIFIER_3, notify_callback_udata, (void *)(intptr_t) udata1, NULL); + assert_in_range(id1, 1, INT_MAX); + + /* 2nd notifier */ + id2 = syscommon_notifier_subscribe_notify_udata(SYSCOMMON_NOTIFIER_3, notify_callback_udata, (void *)(intptr_t) udata2, NULL); + assert_in_range(id2, 1, INT_MAX); + + /* expect invocation of 1st callback and check parameter */ + expect_value(notify_callback_udata, data, (void *)(intptr_t) notify_data); + expect_value(notify_callback_udata, udata, (void *)(intptr_t) udata1); + /* expect invocation of 2nd callback and check parameter */ + expect_value(notify_callback_udata, data, (void *)(intptr_t) notify_data); + expect_value(notify_callback_udata, udata, (void *)(intptr_t) udata2); + + syscommon_notifier_emit_notify(SYSCOMMON_NOTIFIER_3, (void *)(intptr_t) notify_data); + + /* second run. at this time syscommon_notifier_emit_notify() after unregistering 1st notifier */ + notify_data = 0x345; + + syscommon_notifier_unsubscribe_notify_udata(id1); + + /* only expect invocation of 2nd callback and check parameter */ + expect_value(notify_callback_udata, data, (void *)(intptr_t) notify_data); + expect_value(notify_callback_udata, udata, (void *)(intptr_t) udata2); + + syscommon_notifier_emit_notify(SYSCOMMON_NOTIFIER_3, (void *)(intptr_t) notify_data); +} + +static void test_syscommon_notifier_emit_notify_once_p(void **state) +{ + int retval; + + retval = syscommon_notifier_subscribe_notify(SYSCOMMON_NOTIFIER_4, notify_callback); + assert_int_equal(retval, 0); + + expect_value(notify_callback, data, (void *)(intptr_t) 0xabcdabcd); + syscommon_notifier_emit_notify_once(SYSCOMMON_NOTIFIER_4, (void *)(intptr_t) 0xabcdabcd); + + /* Don't add expect_value() for callback at this time. + * Therefore if the callback is invoked, check_expected() returns error */ + syscommon_notifier_emit_notify(SYSCOMMON_NOTIFIER_4, (void *)(intptr_t) 0xabcdabcd); + + retval = syscommon_notifier_subscribe_notify_udata(SYSCOMMON_NOTIFIER_5, notify_callback_udata, (void *)(intptr_t) 0xfefefefe, NULL); + assert_in_range(retval, 1, INT_MAX); + + expect_value(notify_callback_udata, data, (void *)(intptr_t) 0x34343434); + expect_value(notify_callback_udata, udata, (void *)(intptr_t) 0xfefefefe); + syscommon_notifier_emit_notify_once(SYSCOMMON_NOTIFIER_5, (void *)(intptr_t) 0x34343434); + + /* Don't add expect_value() for callback at this time. + * Therefore if the callback is invoked, check_expected() returns error */ + syscommon_notifier_emit_notify(SYSCOMMON_NOTIFIER_5, (void *)(intptr_t) 0x34343434); +} + +static void test_destroy_callback_p1(void **state) +{ + int id; + + id = syscommon_notifier_subscribe_notify_udata(SYSCOMMON_NOTIFIER_6, notify_callback_udata, + (void *)(intptr_t) 0x4848, destroy_callback_udata); + assert_in_range(id, 1, INT_MAX); + + expect_value(destroy_callback_udata, udata, (void *)(intptr_t) 0x4848); + + syscommon_notifier_unsubscribe_notify_udata(id); +} + +static void test_destroy_callback_p2(void **state) +{ + int id; + + id = syscommon_notifier_subscribe_notify_udata(SYSCOMMON_NOTIFIER_6, notify_callback_udata, + (void *)(intptr_t) 0x1177, destroy_callback_udata); + assert_in_range(id, 1, INT_MAX); + + expect_value(notify_callback_udata, data, (void *)(intptr_t) 0x9a9a9a9a); + expect_value(notify_callback_udata, udata, (void *)(intptr_t) 0x1177); + expect_value(destroy_callback_udata, udata, (void *)(intptr_t) 0x1177); + + syscommon_notifier_emit_notify_once(SYSCOMMON_NOTIFIER_6, (void *)(intptr_t) 0x9a9a9a9a); +} + +static void test_destroy_callback_p3(void **state) +{ + int retval; + + retval = syscommon_notifier_subscribe_notify(SYSCOMMON_NOTIFIER_7, notify_callback); + assert_int_equal(retval, 0); + expect_value(notify_callback, data, (void *)(intptr_t) 0x3f3f3f3f); + syscommon_notifier_emit_notify(SYSCOMMON_NOTIFIER_7, (void *)(intptr_t) 0x3f3f3f3f); + + /* notify_callback() should not be invoked */ + syscommon_notifier_unsubscribe_notify(SYSCOMMON_NOTIFIER_7, notify_callback); + syscommon_notifier_emit_notify(SYSCOMMON_NOTIFIER_7, (void *)(intptr_t) 0x34ab34ab); + + /* if a notifier have successfully been deleted, + * re-registering the notifier must be successful */ + retval = syscommon_notifier_subscribe_notify(SYSCOMMON_NOTIFIER_7, notify_callback); + assert_int_equal(retval, 0); + + expect_value(notify_callback, data, (void *)(intptr_t) 0x7878444); + syscommon_notifier_emit_notify(SYSCOMMON_NOTIFIER_7, (void *)(intptr_t) 0x7878444); +} + +static void test_syscommon_notifier_emit_notify_priority_p1(void **state) +{ + int id1, id2, id3; + + id1 = syscommon_notifier_subscribe_notify_udata_priority(SYSCOMMON_NOTIFIER_8, notify_callback_udata, + (void *)(intptr_t) 0x11111111, NULL, -300); + assert_in_range(id1, 1, INT_MAX); + + id2 = syscommon_notifier_subscribe_notify_udata_priority(SYSCOMMON_NOTIFIER_8, notify_callback_udata, + (void *)(intptr_t) 0x22222222, NULL, 500); + assert_in_range(id2, 1, INT_MAX); + + id3 = syscommon_notifier_subscribe_notify_udata_priority(SYSCOMMON_NOTIFIER_8, notify_callback_udata, + (void *)(intptr_t) 0x33333333, NULL, -300); + assert_in_range(id3, 1, INT_MAX); + + /* id2 will be invoked first */ + expect_value(notify_callback_udata, data, (void *)(intptr_t) 0x1234); + expect_value(notify_callback_udata, udata, (void *)(intptr_t) 0x22222222); + /* id1, id3 invocation follows it, + * and those are invoked in the order in which they were registered */ + expect_value(notify_callback_udata, data, (void *)(intptr_t) 0x1234); + expect_value(notify_callback_udata, udata, (void *)(intptr_t) 0x11111111); + expect_value(notify_callback_udata, data, (void *)(intptr_t) 0x1234); + expect_value(notify_callback_udata, udata, (void *)(intptr_t) 0x33333333); + + syscommon_notifier_emit_notify(SYSCOMMON_NOTIFIER_8, (void *)(intptr_t)0x1234); +} + int run_test_suite(void) { const struct CMUnitTest testsuite[] = { @@ -286,6 +514,14 @@ int run_test_suite(void) cmocka_unit_test(test_init_bitmap_n), cmocka_unit_test(test_test_bit), cmocka_unit_test(test_all_bit), + cmocka_unit_test(test_syscommon_notifier_emit_notify_p1), + cmocka_unit_test(test_syscommon_notifier_emit_notify_p2), + cmocka_unit_test(test_syscommon_notifier_emit_notify_p3), + cmocka_unit_test(test_syscommon_notifier_emit_notify_once_p), + cmocka_unit_test(test_destroy_callback_p1), + cmocka_unit_test(test_destroy_callback_p2), + cmocka_unit_test(test_destroy_callback_p3), + cmocka_unit_test(test_syscommon_notifier_emit_notify_priority_p1), }; return cmocka_run_group_tests(testsuite, NULL, NULL);