diff --git a/include/tr/event_dispatcher.h b/include/tr/event_dispatcher.h index 47de8e0..06d1d37 100644 --- a/include/tr/event_dispatcher.h +++ b/include/tr/event_dispatcher.h @@ -32,6 +32,11 @@ TR_CLASS(TR_EventDispatcher); +typedef enum TR_EventDone_e { + TR_EVENT_DONE = 0, + TR_EVENT_PENDING +} TR_EventDone; + #include "tr/event_handler.h" typedef enum TR_e_EventDispatcherMode { diff --git a/include/tr/event_handler.h b/include/tr/event_handler.h index 6a0856f..e19d2ee 100644 --- a/include/tr/event_handler.h +++ b/include/tr/event_handler.h @@ -35,7 +35,7 @@ TR_CLASS(TR_EventHandler); #include "tr/event_dispatcher.h" -typedef int (* TR_EventMethod_fptr)(TR_EventHandler, TR_Event); +typedef TR_EventDone (* TR_EventMethod_fptr)(TR_EventHandler, TR_Event); TR_CLASS(TR_EventHandler) { TR_EventDispatcher dispatcher[10]; @@ -46,9 +46,9 @@ TR_CLASSVARS_DECL(TR_EventHandler) { TR_Hash event_methods; }; -void TR_eventHandlerSetDispatcher(TR_EventHandler, TR_EventDispatcher); -void TR_eventHandlerIssueEvent(TR_EventHandler, TR_Event); -int TR_eventHandlerHandleEvent(TR_EventHandler, TR_Event); +void TR_eventHandlerSetDispatcher(TR_EventHandler, TR_EventDispatcher); +void TR_eventHandlerIssueEvent(TR_EventHandler, TR_Event); +TR_EventDone TR_eventHandlerHandleEvent(TR_EventHandler, TR_Event); #define TR_eventHandlerClassCleanup(cname) \ (TR__eventHandlerClassCleanup(TR_CLASS_BY_NAME(cname))) @@ -68,7 +68,6 @@ void TR__eventHandlerClassCleanup(TR_class_ptr); sizeof(TR_EventMethod_fptr))); \ } while(0) - #endif // __TR_EVENT_HANDLER_H__ // vim: set ts=4 sw=4: diff --git a/src/event_dispatcher_start.c b/src/event_dispatcher_start.c index 515c0ef..c43eb10 100644 --- a/src/event_dispatcher_start.c +++ b/src/event_dispatcher_start.c @@ -38,7 +38,9 @@ TR_eventDispatcherStart(TR_EventDispatcher this) while (this->running || (! TR_queueEmpty(this->events))) { struct timespec tp; int now; // milliseconds - TR_Event current = NULL; + TR_Event event; + TR_Queue handler_queue; + TR_HashValue handler_queue_hv; clock_gettime(CLOCK_REALTIME, &tp); now = tp.tv_sec * 1000 + tp.tv_nsec / 1000000; @@ -55,43 +57,49 @@ TR_eventDispatcherStart(TR_EventDispatcher this) if (TR_queueEmpty(this->events)) { if (TR_EVD_CLIENT == this->mode) { - current = TR_eventSubjectEmit( + event = TR_eventSubjectEmit( (TR_EventSubject)this, TR_DISPATCHER_EVENT_USER_WAIT, NULL); } else { - current = TR_eventSubjectEmit( + event = TR_eventSubjectEmit( (TR_EventSubject)this, TR_DISPATCHER_EVENT_DATA_WAIT, NULL); } } else { - current = TR_queueGet(this->events); + event = TR_queueGet(this->events); } - if (current) { - TR_Queue handler_queue; - TR_HashValue handler_queue_hv = TR_hashGetByVal( - this->handler, - TR_sdbm( - (unsigned char *)&(current->id), - sizeof(current->id))); - - handler_queue = handler_queue_hv - ? *(TR_Queue *)handler_queue_hv->value - : NULL; - - if (handler_queue && ! TR_queueEmpty(handler_queue)) { - TR_Queue queue_node = handler_queue->first; - - while (queue_node) { - TR_EventHandler handler = queue_node->msg; - if (TR_eventHandlerHandleEvent(handler, current)) break; - queue_node = queue_node->next; - } + handler_queue_hv = TR_hashGetByVal( + this->handler, + TR_sdbm( + (unsigned char *)&(event->id), + sizeof(event->id))); + + handler_queue = handler_queue_hv + ? *(TR_Queue *)handler_queue_hv->value + : NULL; + + if (handler_queue && ! TR_queueEmpty(handler_queue)) { + TR_Queue queue_node = handler_queue->first; + TR_EventDone done; + + while (queue_node) { + TR_EventHandler handler = queue_node->msg; + TR_EventDone this_done; + + this_done = TR_eventHandlerHandleEvent(handler, event); + done = TR_EVENT_DONE == done ? done : this_done; + + queue_node = queue_node->next; } - TR_delete(current); + if (TR_EVENT_DONE == done) { + TR_delete(event); + } else { + TR_eventDispatcherEnqueueEvent(this, event); + } } } } diff --git a/src/event_handler_handle_event.c b/src/event_handler_handle_event.c index a980fb4..634d656 100644 --- a/src/event_handler_handle_event.c +++ b/src/event_handler_handle_event.c @@ -27,7 +27,7 @@ #include "tr/event.h" #include "tr/event_handler.h" -int +TR_EventDone TR_eventHandlerHandleEvent(TR_EventHandler this, TR_Event event) { TR_EventMethod_fptr event_func = NULL;