#include "list.h"
#include "common.h"
-struct device_notifier {
- bool deleted;
- enum device_notifier_type status;
- int (*func)(void *data, void *user_data);
- void *user_data;
-};
+#define DEVICE_NOTIFIER_MAX_COUNT 255
static dd_list *device_notifier_list;
static Ecore_Idler *idl;
+static struct device_notifier device_notifiers[DEVICE_NOTIFIER_MAX_COUNT];
+
+#define FIND_NOTIFIER(a, b, c, d, e, f) \
+ DD_LIST_FOREACH(a, b, c) \
+ if (d == c->d && e == (c->e) && f == (c->f))
+
+static struct device_notifier *get_device_notifier(void) {
+ static int pos = 0;
+
+ if ((pos < DEVICE_NOTIFIER_MAX_COUNT) &&
+ (!device_notifiers[pos].is_used)) {
+ device_notifiers[pos].is_used = true;
+ return &device_notifiers[pos++];
+ } else {
+ for (pos = 0; pos < DEVICE_NOTIFIER_MAX_COUNT; pos++) {
+ if (!device_notifiers[pos].is_used) {
+ device_notifiers[pos].is_used = true;
+ return &device_notifiers[pos];
+ }
+ }
+ }
-#define FIND_NOTIFIER(a, b, d, e, f) \
- DD_LIST_FOREACH(a, b, d) \
- if (e == d->e && f == (d->f))
+ return NULL;
+}
int register_notifier(enum device_notifier_type status,
int (*func)(void *data, void *user_data), void *user_data)
{
struct device_notifier *notifier;
- if (!func) {
- _E("invalid func address!");
+ if (status >= DEVICE_NOTIFIER_MAX)
+ return -EINVAL;
+
+ if (!func)
return -EINVAL;
- }
- notifier = calloc(1, sizeof(struct device_notifier));
- if (!notifier) {
- _E("Fail to malloc for notifier!");
+ notifier = get_device_notifier();
+ if (!notifier)
return -ENOMEM;
- }
notifier->status = status;
notifier->func = func;
}
int unregister_notifier(enum device_notifier_type status,
- int (*func)(void *data, void *user_data))
+ int (*func)(void *data, void *user_data), void *user_data)
{
dd_list *n;
struct device_notifier *notifier;
- if (!func) {
- _E("invalid func address!");
- return -EINVAL;
- }
-
- FIND_NOTIFIER(device_notifier_list, n, notifier, status, func) {
- _I("[%d, %x]", status, func);
- notifier->deleted = true;
+ FIND_NOTIFIER(device_notifier_list, n, notifier, status, func,
+ user_data) {
+ notifier->is_used = false;
}
return 0;
struct device_notifier *notifier;
DD_LIST_FOREACH_SAFE(device_notifier_list, n, next, notifier) {
- if (notifier->deleted) {
+ if (!notifier->is_used) {
+ memset(notifier, 0, sizeof(*notifier));
DD_LIST_REMOVE_LIST(device_notifier_list, n);
- free(notifier);
}
}
struct device_notifier *notifier;
DD_LIST_FOREACH(device_notifier_list, n, notifier) {
- if (!notifier->deleted && status == notifier->status) {
+ if (notifier->is_used && status == notifier->status) {
if (notifier->func)
notifier->func(data, notifier->user_data);
}
#ifndef __DEVICE_NOTIFIER_H__
#define __DEVICE_NOTIFIER_H__
+#include <stdbool.h>
+
enum device_notifier_type {
DEVICE_NOTIFIER_BOOTING_DONE,
DEVICE_NOTIFIER_PMQOS,
DEVICE_NOTIFIER_MAX,
};
+struct device_notifier {
+ bool is_used;
+ enum device_notifier_type status;
+ int (*func)(void *data, void *user_data);
+ void *user_data;
+};
+
/*
* This is for internal callback method.
*/
int register_notifier(enum device_notifier_type status,
int (*func)(void *data, void *user_data), void *user_data);
int unregister_notifier(enum device_notifier_type status,
- int (*func)(void *data, void *user_data));
+ int (*func)(void *data, void *user_data), void *user_data);
void device_notify(enum device_notifier_type status, void *value);
#endif /* __DEVICE_NOTIFIER_H__ */
{
int ret;
- register_notifier(DEVICE_NOTIFIER_POWEROFF, device_change_poweroff,
- NULL);
+ ret = register_notifier(DEVICE_NOTIFIER_POWEROFF,
+ device_change_poweroff, NULL);
+ if (ret < 0)
+ _E("cannot register power-off notifier for the udev (%d)\n",
+ ret);
ret = register_edbus_method(PASS_PATH_SYSNOTI,
edbus_methods, ARRAY_SIZE(edbus_methods));
static void udev_exit(void *data)
{
- unregister_notifier(DEVICE_NOTIFIER_POWEROFF, device_change_poweroff);
+ unregister_notifier(DEVICE_NOTIFIER_POWEROFF,
+ device_change_poweroff, NULL);
}
static const struct device_ops udev_device_ops = {
static int pass_notifier_init(struct pass_policy *policy)
{
/* Register DEVICE_NOTIFIER_PMQOS */
- register_notifier(DEVICE_NOTIFIER_PMQOS, pass_notifier_pmqos, policy);
-
- return 0;
+ return register_notifier(DEVICE_NOTIFIER_PMQOS, pass_notifier_pmqos,
+ policy);
}
/*
static int pass_notifier_exit(struct pass_policy *policy)
{
/* Un-register DEVICE_NOTIFIER_PMQOS */
- unregister_notifier(DEVICE_NOTIFIER_PMQOS, pass_notifier_pmqos);
+ unregister_notifier(DEVICE_NOTIFIER_PMQOS, pass_notifier_pmqos,
+ policy);
return 0;
}
{
struct pass_resource *res = to_pass_resource(policy);
struct pass_conf_data *cdata = &res->cdata;
+ int ret;
if(policy->gov_timeout < 0) {
_E("invalid timeout value [%d]!", policy->gov_timeout);
/* Set default PASS state */
policy->gov_state = PASS_GOV_STOP;
- pass_notifier_init(policy);
+ ret = pass_notifier_init(policy);
+ if (ret < 0) {
+ _E("cannot initialize notifier for the pmqos (%d)\n", ret);
+ return ret;
+ }
_I("Initialize governor for '%s' resource", cdata->res_name);