src/lib/event_handler.c in trema-0.4.5 vs src/lib/event_handler.c in trema-0.4.6
- old
+ new
@@ -21,10 +21,11 @@
#include <string.h>
#include <sys/time.h>
#include <unistd.h>
#include "checks.h"
#include "event_handler.h"
+#include "external_callback.h"
#include "log.h"
#include "timer.h"
#ifdef UNIT_TESTING
@@ -59,10 +60,34 @@
#undef execute_timer_events
#endif
#define execute_timer_events mock_execute_timer_events
extern void mock_execute_timer_events( int *next_timeout_usec );
+#ifdef init_external_callback
+#undef init_external_callback
+#endif
+#define init_external_callback mock_init_external_callback
+extern void mock_init_external_callback( void );
+
+#ifdef finalize_external_callback
+#undef finalize_external_callback
+#endif
+#define finalize_external_callback mock_finalize_external_callback
+extern void mock_finalize_external_callback( void );
+
+#ifdef push_external_callback
+#undef push_external_callback
+#endif
+#define push_external_callback mock_push_external_callback
+extern void mock_push_external_callback( external_callback_t callback );
+
+#ifdef run_external_callback
+#undef run_external_callback
+#endif
+#define run_external_callback mock_run_external_callback
+extern void mock_run_external_callback( void );
+
#endif // UNIT_TESTING
typedef struct {
int fd;
@@ -92,23 +117,23 @@
fd_set current_read_set;
fd_set current_write_set;
int fd_set_size = 0;
-external_callback_t external_callback = ( external_callback_t ) NULL;
-
-
static void
_init_event_handler() {
event_last = event_list;
- event_handler_state = EVENT_HANDLER_INITIALIZED;
memset( event_list, 0, sizeof( event_fd ) * FD_SETSIZE );
memset( event_fd_set, 0, sizeof( event_fd * ) * FD_SETSIZE );
FD_ZERO( &event_read_set );
FD_ZERO( &event_write_set );
+
+ init_external_callback();
+
+ event_handler_state = EVENT_HANDLER_INITIALIZED;
}
void ( *init_event_handler )() = _init_event_handler;
static void
@@ -118,53 +143,70 @@
( event_last - event_list ), ( event_last > event_list ? event_list->fd : -1 ) );
return;
}
event_handler_state = EVENT_HANDLER_FINALIZED;
+
+ finalize_external_callback();
}
void ( *finalize_event_handler )() = _finalize_event_handler;
static bool
_run_event_handler_once( int timeout_usec ) {
- if ( external_callback != NULL ) {
- external_callback_t callback = external_callback;
- external_callback = NULL;
+ run_external_callback();
- callback();
- }
-
memcpy( ¤t_read_set, &event_read_set, sizeof( fd_set ) );
memcpy( ¤t_write_set, &event_write_set, sizeof( fd_set ) );
struct timeval timeout;
timeout.tv_sec = timeout_usec / 1000000;
timeout.tv_usec = timeout_usec % 1000000;
int set_count = select( fd_set_size, ¤t_read_set, ¤t_write_set, NULL, &timeout );
if ( set_count == -1 ) {
if ( errno == EINTR ) {
+ run_external_callback();
return true;
}
error( "Failed to select ( errno = %s [%d] ).", strerror( errno ), errno );
return false;
}
else if ( set_count == 0 ) {
// timed out
+ run_external_callback();
return true;
}
- event_fd *event_itr = event_list;
+ run_external_callback();
+ event_fd *event_itr = event_list;
while ( event_itr < event_last ) {
event_fd current_event = *event_itr;
if ( FD_ISSET( current_event.fd, ¤t_write_set ) ) {
current_event.write_callback( current_event.fd, current_event.write_data );
}
+ // In the rare cases the current fd is closed, a new one is opened
+ // with the same fd and is put in the same location we can just
+ // wait for the next select call.
+ if ( current_event.fd == event_itr->fd ) {
+ event_itr = event_itr + 1;
+ }
+ else {
+ debug( "run_event_handler_once: event fd is changed ( current = %d, new = %d )", current_event.fd, event_itr->fd );
+ }
+ }
+
+ run_external_callback();
+
+ event_itr = event_list;
+ while ( event_itr < event_last ) {
+ event_fd current_event = *event_itr;
+
if ( FD_ISSET( current_event.fd, ¤t_read_set ) ) {
current_event.read_callback( current_event.fd, current_event.read_data );
}
// In the rare cases the current fd is closed, a new one is opened
@@ -176,10 +218,12 @@
else {
debug( "run_event_handler_once: event fd is changed ( current = %d, new = %d )", current_event.fd, event_itr->fd );
}
}
+ run_external_callback();
+
return true;
}
bool ( *run_event_handler_once )( int ) = _run_event_handler_once;
@@ -363,21 +407,9 @@
static bool
_writable( int fd ) {
return FD_ISSET( fd, &event_write_set );
}
bool ( *writable )( int fd ) = _writable;
-
-
-static bool
-_set_external_callback( external_callback_t callback ) {
- if ( external_callback != NULL ) {
- return false;
- }
-
- external_callback = callback;
- return true;
-}
-bool ( *set_external_callback )( external_callback_t callback ) = _set_external_callback;
/*
* Local variables:
* c-basic-offset: 2