summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYoungjae Cho <y0.cho@samsung.com>2021-05-04 19:10:13 +0900
committerYoungjae Cho <y0.cho@samsung.com>2021-05-04 21:42:42 +0900
commit8477eeb9530b03a650ca02dc9a894fbd10dc213d (patch)
treeaec17c91ac36a07f17ea96f2b602069184bd61ea
parent1e415c56febd95a98502ff1bef69c18d6c353430 (diff)
downloaddevice-common-8477eeb9530b03a650ca02dc9a894fbd10dc213d.tar.gz
device-common-8477eeb9530b03a650ca02dc9a894fbd10dc213d.tar.bz2
device-common-8477eeb9530b03a650ca02dc9a894fbd10dc213d.zip
udev_control_kernel_start() can be invoked multiple times from multiple hal-backend modules. Therefore do not return error for duplicate invocation. Change-Id: Icd3586aec4281ad23b39c26a21d7cff13a8ca80b Signed-off-by: Youngjae Cho <y0.cho@samsung.com>
-rw-r--r--src/udev/udev.c69
1 files changed, 25 insertions, 44 deletions
diff --git a/src/udev/udev.c b/src/udev/udev.c
index f2a4a3d..291e605 100644
--- a/src/udev/udev.c
+++ b/src/udev/udev.c
@@ -35,11 +35,12 @@ struct uevent_info {
GIOChannel *ch;
guint eventid;
GList *event_list;
+ int ref;
+ struct udev *udev;
};
/* Uevent */
-static struct udev *udev;
static struct uevent_info kevent; /* kernel */
static struct uevent_info uevent; /* udev */
@@ -89,6 +90,9 @@ static int uevent_control_stop(struct uevent_info *info)
if (!info)
return -EINVAL;
+ if (--info->ref > 0)
+ return 0;
+
if (info->eventid) {
g_source_remove(info->eventid);
info->eventid = 0;
@@ -104,37 +108,34 @@ static int uevent_control_stop(struct uevent_info *info)
udev_monitor_unref(info->mon);
info->mon = NULL;
}
- if (udev)
- udev = udev_unref(udev);
+ if (info->udev)
+ info->udev = udev_unref(info->udev);
+
return 0;
}
static int uevent_control_start(const char *type,
struct uevent_info *info)
{
- struct uevent_handler *l;
- GList *elem;
int fd;
int ret;
if (!info)
return -EINVAL;
- if (info->mon) {
- _E("%s uevent control routine is alreay started", type);
- return -EINVAL;
- }
-
- if (!udev) {
- udev = udev_new();
- if (!udev) {
+ if (!info->udev) {
+ info->udev = udev_new();
+ if (!info->udev) {
_E("error create udev");
return -EINVAL;
}
- } else
- udev = udev_ref(udev);
+ info->ref = 1;
+ } else {
+ ++info->ref;
+ return 0;
+ }
- info->mon = udev_monitor_new_from_netlink(udev, type);
+ info->mon = udev_monitor_new_from_netlink(info->udev, type);
if (info->mon == NULL) {
_E("error udev_monitor create");
goto stop;
@@ -148,21 +149,6 @@ static int uevent_control_start(const char *type,
goto stop;
}
- for (elem = info->event_list ; elem ; elem = g_list_next(elem)) {
- l = elem->data;
- ret = udev_monitor_filter_add_match_subsystem_devtype(
- info->mon,
- l->subsystem, NULL);
- if (ret < 0) {
- _E("error apply subsystem filter");
- goto stop;
- }
- }
-
- ret = udev_monitor_filter_update(info->mon);
- if (ret < 0)
- _E("error udev_monitor_filter_update");
-
fd = udev_monitor_get_fd(info->mon);
if (fd == -1) {
_E("error udev_monitor_get_fd");
@@ -214,34 +200,29 @@ static int register_uevent_control(struct uevent_info *info,
struct uevent_handler *l;
GList *elem;
int r;
- bool matched = false;
int len;
if (!info || !uh || !uh->subsystem)
return -EINVAL;
/* if udev is not initialized, it just will be added list */
- if (!udev || !info->mon)
+ if (!info->udev || !info->mon)
goto add_list;
len = strlen(uh->subsystem);
/* check if the same subsystem is already added */
for (elem = info->event_list; elem ; elem = g_list_next(elem)) {
l = elem->data;
- if (!strncmp(l->subsystem, uh->subsystem, len)) {
- matched = true;
- break;
- }
+ if (!strncmp(l->subsystem, uh->subsystem, len))
+ goto add_list;
}
/* the first request to add subsystem */
- if (!matched) {
- r = udev_monitor_filter_add_match_subsystem_devtype(info->mon,
- uh->subsystem, NULL);
- if (r < 0) {
- _E("fail to add %s subsystem : %d", uh->subsystem, r);
- return -EPERM;
- }
+ r = udev_monitor_filter_add_match_subsystem_devtype(info->mon,
+ uh->subsystem, NULL);
+ if (r < 0) {
+ _E("fail to add %s subsystem : %d", uh->subsystem, r);
+ return -EPERM;
}
r = udev_monitor_filter_update(info->mon);