summaryrefslogtreecommitdiff
path: root/src/event.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/event.c')
-rw-r--r--src/event.c231
1 files changed, 122 insertions, 109 deletions
diff --git a/src/event.c b/src/event.c
index 818e66f..89c4e34 100644
--- a/src/event.c
+++ b/src/event.c
@@ -36,38 +36,6 @@
#include "conf.h"
#include "event.h"
-#define CRITICAL_SECTION_BEGIN(lock) do { \
- int ret; \
- ret = pthread_mutex_lock(&lock); \
- if (ret != 0) { \
- ErrPrint("Unable to get lock: %s\n", strerror(ret)); \
- } \
-} while (0)
-
-#define CRITICAL_SECTION_END(lock) do { \
- int ret; \
- ret = pthread_mutex_unlock(&lock); \
- if (ret != 0) { \
- ErrPrint("Unable to unlock: %s\n", strerror(ret)); \
- } \
-} while (0)
-
-#define CANCEL_SECTION_BEGIN() do { \
- int ret; \
- ret = pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL); \
- if (ret != 0) \
- ErrPrint("Unable to set cancelate state: %s\n", strerror(ret)); \
-} while (0)
-
-#define CANCEL_SECTION_END() do { \
- int ret; \
- ret = pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL); \
- if (ret != 0) \
- ErrPrint("Unable to set cancelate state: %s\n", strerror(ret)); \
-} while (0)
-
-#define PIPE_READ 0
-#define PIPE_WRITE 1
#define EVENT_CH 'e'
int errno;
@@ -77,8 +45,10 @@ static struct info {
Eina_List *event_list;
int handle;
pthread_mutex_t event_list_lock;
- int evt_pipe[2];
+ int evt_pipe[PIPE_MAX];
+ int tcb_pipe[PIPE_MAX];
Ecore_Fd_Handler *event_handler;
+ Ecore_Fd_Handler *tcb_handler;
int (*event_cb)(enum event_state state, struct event_data *event, void *data);
void *cbdata;
@@ -144,9 +114,9 @@ static inline int processing_input_event(struct input_event *event)
memcpy(item, &s_info.event_data, sizeof(*item));
- CRITICAL_SECTION_BEGIN(s_info.event_list_lock);
+ CRITICAL_SECTION_BEGIN(&s_info.event_list_lock);
s_info.event_list = eina_list_append(s_info.event_list, item);
- CRITICAL_SECTION_END(s_info.event_list_lock);
+ CRITICAL_SECTION_END(&s_info.event_list_lock);
event_ch = EVENT_CH;
if (write(s_info.evt_pipe[PIPE_WRITE], &event_ch, sizeof(event_ch)) != sizeof(event_ch)) {
@@ -225,7 +195,7 @@ static inline int processing_input_event(struct input_event *event)
return LB_STATUS_SUCCESS;
}
-static void *event_main(void *data)
+static void *event_thread_main(void *data)
{
fd_set set;
int ret = 0;
@@ -233,11 +203,11 @@ static void *event_main(void *data)
char *ptr = (char *)&input_event;
int offset = 0;
int readsize = 0;
+ char event_ch = EVENT_CH;
- DbgPrint("event_main initiated\n");
+ DbgPrint("Initiated\n");
while (1) {
- CANCEL_SECTION_BEGIN();
FD_ZERO(&set);
FD_SET(s_info.handle, &set);
ret = select(s_info.handle + 1, &set, NULL, NULL, NULL);
@@ -245,18 +215,15 @@ static void *event_main(void *data)
ret = -errno;
if (errno == EINTR) {
DbgPrint("Select receives INTR\n");
- CANCEL_SECTION_END();
continue;
}
ErrPrint("Error: %s\n", strerror(errno));
- CANCEL_SECTION_END();
- return (void *)ret;
+ break;
} else if (ret == 0) {
ErrPrint("Timeout expired\n");
- CANCEL_SECTION_END();
- return (void *)LB_STATUS_ERROR_TIMEOUT;
+ ret = LB_STATUS_ERROR_TIMEOUT;
+ break;
}
- CANCEL_SECTION_END();
if (!FD_ISSET(s_info.handle, &set)) {
ErrPrint("Unexpected handle is toggled\n");
@@ -281,9 +248,84 @@ static void *event_main(void *data)
}
}
+ if (write(s_info.tcb_pipe[PIPE_WRITE], &event_ch, sizeof(event_ch)) != sizeof(event_ch))
+ ErrPrint("Unable to write PIPE: %s\n", strerror(errno));
+
return (void *)ret;
}
+static inline int reclaim_tcb_resources(void)
+{
+ int status;
+ struct event_data *event;
+ void *ret;
+
+ if (close(s_info.handle) < 0)
+ ErrPrint("Unable to release the fd: %s\n", strerror(errno));
+
+ s_info.handle = -1;
+ DbgPrint("Event handler deactivated\n");
+
+ status = pthread_join(s_info.tid, &ret);
+ if (status != 0)
+ ErrPrint("Failed to join a thread: %s\n", strerror(errno));
+ else
+ DbgPrint("Thread returns: %d\n", (int)ret);
+
+ ecore_main_fd_handler_del(s_info.event_handler);
+ s_info.event_handler = NULL;
+
+ ecore_main_fd_handler_del(s_info.tcb_handler);
+ s_info.tcb_handler = NULL;
+
+ CLOSE_PIPE(s_info.tcb_pipe);
+ CLOSE_PIPE(s_info.evt_pipe);
+
+ EINA_LIST_FREE(s_info.event_list, event) {
+ if (s_info.event_cb) {
+ if (s_info.event_state == EVENT_STATE_DEACTIVATE) {
+ s_info.event_state = EVENT_STATE_ACTIVATE;
+ } else if (s_info.event_state == EVENT_STATE_ACTIVATE) {
+ s_info.event_state = EVENT_STATE_ACTIVATED;
+ }
+ s_info.event_cb(s_info.event_state, event, s_info.cbdata);
+ }
+ free(event);
+ }
+
+ if (s_info.event_state != EVENT_STATE_DEACTIVATE) {
+ s_info.event_state = EVENT_STATE_DEACTIVATE;
+
+ if (s_info.event_cb)
+ s_info.event_cb(s_info.event_state, &s_info.event_data, s_info.cbdata);
+ }
+
+ s_info.event_data.x = -1;
+ s_info.event_data.y = -1;
+ return LB_STATUS_SUCCESS;
+}
+
+static Eina_Bool event_deactivate_cb(void *data, Ecore_Fd_Handler *handler)
+{
+ int fd;
+ char event_ch;
+
+ fd = ecore_main_fd_handler_fd_get(handler);
+ if (fd < 0) {
+ ErrPrint("Invalid fd\n");
+ return ECORE_CALLBACK_CANCEL;
+ }
+
+ if (read(fd, &event_ch, sizeof(event_ch)) != sizeof(event_ch)) {
+ ErrPrint("Unable to read event ch: %s\n", strerror(errno));
+ return ECORE_CALLBACK_CANCEL;
+ }
+
+ DbgPrint("Deactivated event received: %c\n", event_ch);
+ reclaim_tcb_resources();
+ return ECORE_CALLBACK_CANCEL;
+}
+
static Eina_Bool event_read_cb(void *data, Ecore_Fd_Handler *handler)
{
int fd;
@@ -301,13 +343,13 @@ static Eina_Bool event_read_cb(void *data, Ecore_Fd_Handler *handler)
return ECORE_CALLBACK_CANCEL;
}
- CRITICAL_SECTION_BEGIN(s_info.event_list_lock);
+ CRITICAL_SECTION_BEGIN(&s_info.event_list_lock);
item = eina_list_nth(s_info.event_list, 0);
if (item)
s_info.event_list = eina_list_remove(s_info.event_list, item);
else
ErrPrint("Unable to get event\n");
- CRITICAL_SECTION_END(s_info.event_list_lock);
+ CRITICAL_SECTION_END(&s_info.event_list_lock);
if (item && s_info.event_cb) {
switch (s_info.event_state) {
@@ -328,6 +370,9 @@ static Eina_Bool event_read_cb(void *data, Ecore_Fd_Handler *handler)
return ECORE_CALLBACK_RENEW;
}
+/*!
+ * x, y is the starting point.
+ */
HAPI int event_activate(int x, int y, int (*event_cb)(enum event_state state, struct event_data *event, void *data), void *data)
{
int status;
@@ -358,37 +403,56 @@ HAPI int event_activate(int x, int y, int (*event_cb)(enum event_state state, st
return LB_STATUS_ERROR_FAULT;
}
+ status = pipe2(s_info.tcb_pipe, O_NONBLOCK | O_CLOEXEC);
+ if (status < 0) {
+ ErrPrint("Unable to prepare tcb pipe: %s\n", strerror(errno));
+ if (close(s_info.handle) < 0)
+ ErrPrint("Failed to close handle: %s\n", strerror(errno));
+ s_info.handle = -1;
+ CLOSE_PIPE(s_info.evt_pipe);
+ return LB_STATUS_ERROR_FAULT;
+ }
+
s_info.event_handler = ecore_main_fd_handler_add(s_info.evt_pipe[PIPE_READ], ECORE_FD_READ, event_read_cb, NULL, NULL, NULL);
if (!s_info.event_handler) {
if (close(s_info.handle) < 0)
ErrPrint("Failed to close handle: %s\n", strerror(errno));
+ s_info.handle = -1;
- if (close(s_info.evt_pipe[PIPE_READ]) < 0)
- ErrPrint("Failed to close handle: %s\n", strerror(errno));
+ CLOSE_PIPE(s_info.tcb_pipe);
+ CLOSE_PIPE(s_info.evt_pipe);
+ return LB_STATUS_ERROR_FAULT;
+ }
- if (close(s_info.evt_pipe[PIPE_WRITE]) < 0)
- ErrPrint("Failed to close handle: %s\n", strerror(errno));
+ s_info.tcb_handler = ecore_main_fd_handler_add(s_info.tcb_pipe[PIPE_READ], ECORE_FD_READ, event_deactivate_cb, NULL, NULL, NULL);
+ if (!s_info.event_handler) {
+ ecore_main_fd_handler_del(s_info.event_handler);
+ s_info.event_handler = NULL;
+ if (close(s_info.handle) < 0)
+ ErrPrint("Failed to close handle: %s\n", strerror(errno));
s_info.handle = -1;
+
+ CLOSE_PIPE(s_info.tcb_pipe);
+ CLOSE_PIPE(s_info.evt_pipe);
return LB_STATUS_ERROR_FAULT;
}
- status = pthread_create(&s_info.tid, NULL, event_main, NULL);
+ status = pthread_create(&s_info.tid, NULL, event_thread_main, NULL);
if (status != 0) {
ErrPrint("Failed to initiate the thread: %s\n", strerror(status));
ecore_main_fd_handler_del(s_info.event_handler);
s_info.event_handler = NULL;
+ ecore_main_fd_handler_del(s_info.tcb_handler);
+ s_info.tcb_handler = NULL;
+
if (close(s_info.handle) < 0)
ErrPrint("close: %s\n", strerror(errno));
s_info.handle = -1;
- if (close(s_info.evt_pipe[PIPE_READ]) < 0)
- ErrPrint("close: %s\n", strerror(errno));
-
- if (close(s_info.evt_pipe[PIPE_WRITE]) < 0)
- ErrPrint("close: %s\n", strerror(errno));
-
+ CLOSE_PIPE(s_info.tcb_pipe);
+ CLOSE_PIPE(s_info.evt_pipe);
return LB_STATUS_ERROR_FAULT;
}
@@ -403,63 +467,12 @@ HAPI int event_activate(int x, int y, int (*event_cb)(enum event_state state, st
HAPI int event_deactivate(void)
{
- int status;
- struct event_data *event;
- void *ret;
-
if (s_info.handle < 0) {
ErrPrint("Event handler is not actiavated\n");
return LB_STATUS_SUCCESS;
}
- status = pthread_cancel(s_info.tid);
- if (status != 0)
- ErrPrint("Failed to cacnel a thread: %s\n", strerror(errno));
-
- status = pthread_join(s_info.tid, &ret);
- if (status != 0)
- ErrPrint("Failed to join a thread: %s\n", strerror(errno));
- else if (ret == PTHREAD_CANCELED)
- DbgPrint("Thread is canceled\n");
-
- ecore_main_fd_handler_del(s_info.event_handler);
- s_info.event_handler = NULL;
-
- if (close(s_info.evt_pipe[PIPE_READ]) < 0)
- ErrPrint("Failed to close: %s\n", strerror(errno));
-
- if (close(s_info.evt_pipe[PIPE_WRITE]) < 0)
- ErrPrint("Failed to close: %s\n", strerror(errno));
-
- if (close(s_info.handle) < 0)
- ErrPrint("Unable to release the fd: %s\n", strerror(errno));
-
- s_info.handle = -1;
- DbgPrint("Event handler deactivated\n");
-
- EINA_LIST_FREE(s_info.event_list, event) {
- if (s_info.event_cb) {
- if (s_info.event_state == EVENT_STATE_DEACTIVATE) {
- s_info.event_state = EVENT_STATE_ACTIVATE;
- } else if (s_info.event_state == EVENT_STATE_ACTIVATE) {
- s_info.event_state = EVENT_STATE_ACTIVATED;
- }
- s_info.event_cb(s_info.event_state, event, s_info.cbdata);
- }
- free(event);
- }
-
- if (s_info.event_state != EVENT_STATE_DEACTIVATE) {
- s_info.event_state = EVENT_STATE_DEACTIVATE;
-
- if (s_info.event_cb)
- s_info.event_cb(s_info.event_state, &s_info.event_data, s_info.cbdata);
- }
-
- s_info.event_data.x = -1;
- s_info.event_data.y = -1;
-
- return LB_STATUS_SUCCESS;
+ return reclaim_tcb_resources();
}
HAPI int event_is_activated(void)