summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/hardware_legacy/uevent.h3
-rw-r--r--uevent/uevent.c53
2 files changed, 56 insertions, 0 deletions
diff --git a/include/hardware_legacy/uevent.h b/include/hardware_legacy/uevent.h
index 7a5ce58..e4b588b 100644
--- a/include/hardware_legacy/uevent.h
+++ b/include/hardware_legacy/uevent.h
@@ -23,6 +23,9 @@ extern "C" {
int uevent_init();
int uevent_next_event(char* buffer, int buffer_length);
+int uevent_add_native_handler(void (*handler)(void *data, const char *msg, int msg_len),
+ void *handler_data);
+int uevent_remove_native_handler(void (*handler)(void *data, const char *msg, int msg_len));
#if __cplusplus
} // extern "C"
diff --git a/uevent/uevent.c b/uevent/uevent.c
index d1d4b8e..396bad4 100644
--- a/uevent/uevent.c
+++ b/uevent/uevent.c
@@ -19,12 +19,23 @@
#include <string.h>
#include <unistd.h>
#include <poll.h>
+#include <pthread.h>
#include <sys/socket.h>
#include <sys/un.h>
+#include <sys/queue.h>
#include <linux/netlink.h>
+LIST_HEAD(uevent_handler_head, uevent_handler) uevent_handler_list;
+pthread_mutex_t uevent_handler_list_lock = PTHREAD_MUTEX_INITIALIZER;
+
+struct uevent_handler {
+ void (*handler)(void *data, const char *msg, int msg_len);
+ void *handler_data;
+ LIST_ENTRY(uevent_handler) list;
+};
+
static int fd = -1;
/* Returns 0 on failure, 1 on success */
@@ -68,6 +79,12 @@ int uevent_next_event(char* buffer, int buffer_length)
if(nr > 0 && fds.revents == POLLIN) {
int count = recv(fd, buffer, buffer_length, 0);
if (count > 0) {
+ struct uevent_handler *h;
+ pthread_mutex_lock(&uevent_handler_list_lock);
+ LIST_FOREACH(h, &uevent_handler_list, list)
+ h->handler(h->handler_data, buffer, buffer_length);
+ pthread_mutex_unlock(&uevent_handler_list_lock);
+
return count;
}
}
@@ -76,3 +93,39 @@ int uevent_next_event(char* buffer, int buffer_length)
// won't get here
return 0;
}
+
+int uevent_add_native_handler(void (*handler)(void *data, const char *msg, int msg_len),
+ void *handler_data)
+{
+ struct uevent_handler *h;
+
+ h = malloc(sizeof(struct uevent_handler));
+ if (h == NULL)
+ return -1;
+ h->handler = handler;
+ h->handler_data = handler_data;
+
+ pthread_mutex_lock(&uevent_handler_list_lock);
+ LIST_INSERT_HEAD(&uevent_handler_list, h, list);
+ pthread_mutex_unlock(&uevent_handler_list_lock);
+
+ return 0;
+}
+
+int uevent_remove_native_handler(void (*handler)(void *data, const char *msg, int msg_len))
+{
+ struct uevent_handler *h;
+ int err = -1;
+
+ pthread_mutex_lock(&uevent_handler_list_lock);
+ LIST_FOREACH(h, &uevent_handler_list, list) {
+ if (h->handler == handler) {
+ LIST_REMOVE(h, list);
+ err = 0;
+ break;
+ }
+ }
+ pthread_mutex_unlock(&uevent_handler_list_lock);
+
+ return err;
+}