From da727875ac954b13ecb16521d255499511bb7424 Mon Sep 17 00:00:00 2001 From: mannol Date: Sun, 13 Oct 2013 16:16:47 +0200 Subject: tox A/V: RTP/MSI implementation --- toxmsi/toxmsi_event.c | 214 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 214 insertions(+) create mode 100644 toxmsi/toxmsi_event.c (limited to 'toxmsi/toxmsi_event.c') diff --git a/toxmsi/toxmsi_event.c b/toxmsi/toxmsi_event.c new file mode 100644 index 00000000..d8c0d269 --- /dev/null +++ b/toxmsi/toxmsi_event.c @@ -0,0 +1,214 @@ + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif /* HAVE_CONFIG_H */ + +#include + +#include "toxmsi_event.h" + +#include "../toxrtp/toxrtp_helper.h" +#include +#include +#include + +static int _unique_id = 1; + +/* clear events */ +void clear_events (event_container_t** _event_container, size_t* _counter) +{ + assert( *_event_container ); + + free(*_event_container); + *_event_container = NULL; + + *_counter = 0; +} + +int pop_id ( event_container_t** _event_container, size_t* _counter, int _id ) +{ + if ( !*_event_container || !*_counter || !_id ) + return FAILURE; + + event_container_t* _it = *_event_container; + int i; + + for ( i = *_counter; i > 0 ; -- i ){ + if ( _it->_id == _id ) { /* Hit! */ + break; + } + ++_it; + } + + if ( i ) { + for ( ; i > 0; -- i ){ *_it = *(_it + 1); ++_it; } + -- (*_counter); + *_event_container = realloc(*_event_container, sizeof(event_container_t) * (*_counter)); /* resize */ + + if ( *_counter ) + assert(*_event_container); + + return SUCCESS; + + } else { + assert(i); + return FAILURE; + } +} + +/* main poll for event execution */ +void* event_poll( void* _event_handler_p ) +{ + event_handler_t* _event_handler = _event_handler_p; + uint32_t* _frequms = &_event_handler->_frequms; + + + while ( _event_handler->_running ) + { + + if ( _event_handler->_events_count ){ + pthread_mutex_lock(&_event_handler->_mutex); + + int i; + for ( i = 0; i < _event_handler->_events_count; i ++ ){ + _event_handler->_events[i]._event(_event_handler->_events[i]._event_args); + + } + clear_events(&_event_handler->_events, &_event_handler->_events_count); + + pthread_mutex_unlock(&_event_handler->_mutex); + } + + if ( _event_handler->_timed_events_count ){ + pthread_mutex_lock(&_event_handler->_mutex); + + uint32_t _time = t_time(); + + if ( _event_handler->_timed_events[0]._timeout < _time ) { + _event_handler->_timed_events[0]._event(_event_handler->_timed_events[0]._event_args); + + pop_id(&_event_handler->_timed_events, + &_event_handler->_timed_events_count, + _event_handler->_timed_events[0]._id); + } + pthread_mutex_unlock(&_event_handler->_mutex); + } + + + usleep(*_frequms); + } + + _event_handler->_running = -1; + pthread_exit(NULL); +} + +void push_event ( event_container_t** _container, size_t* _counter, event_t _func, event_arg_t _arg ) +{ + (*_counter)++; + (*_container) = realloc((*_container), sizeof(event_container_t) * (*_counter)); + assert((*_container) != NULL); + + (*_container[*_counter - 1])._event = _func; + (*_container[*_counter - 1])._event_args = _arg; + (*_container[*_counter - 1])._timeout = 0; + (*_container[*_counter - 1])._id = 0; +} + +void throw_event( void* _event_handler_p, event_t _func, event_arg_t _arg ) +{ + if ( !_func ) + return; + + event_handler_t* _event_handler = _event_handler_p; + + pthread_mutex_lock(&_event_handler->_mutex); + + push_event(&_event_handler->_events, &_event_handler->_events_count, _func, _arg); + + pthread_mutex_unlock(&_event_handler->_mutex); +} + +int throw_timer_event ( void* _event_handler_p, event_t _func, event_arg_t _arg, uint32_t _timeout) +{ + if ( !_func ) + return FAILURE; + + event_handler_t* _event_handler = _event_handler_p; + + pthread_mutex_lock(&_event_handler->_mutex); + + push_event(&_event_handler->_timed_events, &_event_handler->_timed_events_count, _func, _arg); + size_t _counter = _event_handler->_timed_events_count; + _event_handler->_timed_events[_counter - 1]._timeout = _timeout + t_time(); + _event_handler->_timed_events[_counter - 1]._id = _unique_id; ++_unique_id; + + + /* reorder */ + if ( _counter > 1 ) { + + int i = _counter - 1; + /* start from behind excluding last added member */ + event_container_t* _it = &_event_handler->_timed_events[i - 1]; + + event_container_t _last_added = _event_handler->_timed_events[i]; + + for ( ; i > 0; --i ) { + if ( _it->_timeout > _timeout ){ + *(_it + 1) = *_it; + *_it = _last_added; -- _it; + } + } + + } + + pthread_mutex_unlock(&_event_handler->_mutex); + + return _event_handler->_timed_events[_counter - 1]._id; +} +int cancel_timer_event ( void* _event_handler_p, int _id ) +{ + event_handler_t* _event_handler = _event_handler_p; + return pop_id(&_event_handler->_timed_events, &_event_handler->_timed_events_count, _id); +} + +event_handler_t* init_event_poll (uint32_t _frequms) +{ + event_handler_t* _retu = calloc(sizeof(event_handler_t), 1); + assert(_retu); + /* Initialize basic events */ + _retu->_events = NULL ; + + /* Initialize timed events */ + _retu->_timed_events = NULL; + + _retu->_frequms = _frequms; + _retu->_running = 1; + pthread_mutex_init(&_retu->_mutex, NULL); + + pthread_create(&_retu->_thread_id, NULL, event_poll, _retu); + int _rc = pthread_detach(_retu->_thread_id); + assert(_rc == 0); + + return _retu; +} + +int terminate_event_poll(event_handler_t* _handler) +{ + if ( !_handler ) + return FAILURE; + + _handler->_running = 0; + while (_handler->_running != -1); /* Wait for execution */ + + if (_handler->_events) + clear_events(&_handler->_events, &_handler->_events_count); + if (_handler->_events) + clear_events(&_handler->_timed_events, &_handler->_timed_events_count); + + pthread_mutex_destroy( &_handler->_mutex ); + + free(_handler); + + return SUCCESS; +} + -- cgit v1.2.3