summaryrefslogtreecommitdiff
path: root/toxmsi/toxmsi_event.c
diff options
context:
space:
mode:
authormannol <eniz_vukovic@hotmail.com>2013-10-13 16:16:47 +0200
committerBtbN <btbn@btbn.de>2013-10-13 16:16:47 +0200
commitda727875ac954b13ecb16521d255499511bb7424 (patch)
tree551904f3738612e9c15d98f320c323aa325a5cf8 /toxmsi/toxmsi_event.c
parent1b971de651278429eea312f3240e1c5b8fbc67a4 (diff)
tox A/V: RTP/MSI implementation
Diffstat (limited to 'toxmsi/toxmsi_event.c')
-rw-r--r--toxmsi/toxmsi_event.c214
1 files changed, 214 insertions, 0 deletions
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 @@
1
2#ifdef HAVE_CONFIG_H
3#include "config.h"
4#endif /* HAVE_CONFIG_H */
5
6#include <stdlib.h>
7
8#include "toxmsi_event.h"
9
10#include "../toxrtp/toxrtp_helper.h"
11#include <assert.h>
12#include <stdlib.h>
13#include <unistd.h>
14
15static int _unique_id = 1;
16
17/* clear events */
18void clear_events (event_container_t** _event_container, size_t* _counter)
19{
20 assert( *_event_container );
21
22 free(*_event_container);
23 *_event_container = NULL;
24
25 *_counter = 0;
26}
27
28int pop_id ( event_container_t** _event_container, size_t* _counter, int _id )
29{
30 if ( !*_event_container || !*_counter || !_id )
31 return FAILURE;
32
33 event_container_t* _it = *_event_container;
34 int i;
35
36 for ( i = *_counter; i > 0 ; -- i ){
37 if ( _it->_id == _id ) { /* Hit! */
38 break;
39 }
40 ++_it;
41 }
42
43 if ( i ) {
44 for ( ; i > 0; -- i ){ *_it = *(_it + 1); ++_it; }
45 -- (*_counter);
46 *_event_container = realloc(*_event_container, sizeof(event_container_t) * (*_counter)); /* resize */
47
48 if ( *_counter )
49 assert(*_event_container);
50
51 return SUCCESS;
52
53 } else {
54 assert(i);
55 return FAILURE;
56 }
57}
58
59/* main poll for event execution */
60void* event_poll( void* _event_handler_p )
61{
62 event_handler_t* _event_handler = _event_handler_p;
63 uint32_t* _frequms = &_event_handler->_frequms;
64
65
66 while ( _event_handler->_running )
67 {
68
69 if ( _event_handler->_events_count ){
70 pthread_mutex_lock(&_event_handler->_mutex);
71
72 int i;
73 for ( i = 0; i < _event_handler->_events_count; i ++ ){
74 _event_handler->_events[i]._event(_event_handler->_events[i]._event_args);
75
76 }
77 clear_events(&_event_handler->_events, &_event_handler->_events_count);
78
79 pthread_mutex_unlock(&_event_handler->_mutex);
80 }
81
82 if ( _event_handler->_timed_events_count ){
83 pthread_mutex_lock(&_event_handler->_mutex);
84
85 uint32_t _time = t_time();
86
87 if ( _event_handler->_timed_events[0]._timeout < _time ) {
88 _event_handler->_timed_events[0]._event(_event_handler->_timed_events[0]._event_args);
89
90 pop_id(&_event_handler->_timed_events,
91 &_event_handler->_timed_events_count,
92 _event_handler->_timed_events[0]._id);
93 }
94 pthread_mutex_unlock(&_event_handler->_mutex);
95 }
96
97
98 usleep(*_frequms);
99 }
100
101 _event_handler->_running = -1;
102 pthread_exit(NULL);
103}
104
105void push_event ( event_container_t** _container, size_t* _counter, event_t _func, event_arg_t _arg )
106{
107 (*_counter)++;
108 (*_container) = realloc((*_container), sizeof(event_container_t) * (*_counter));
109 assert((*_container) != NULL);
110
111 (*_container[*_counter - 1])._event = _func;
112 (*_container[*_counter - 1])._event_args = _arg;
113 (*_container[*_counter - 1])._timeout = 0;
114 (*_container[*_counter - 1])._id = 0;
115}
116
117void throw_event( void* _event_handler_p, event_t _func, event_arg_t _arg )
118{
119 if ( !_func )
120 return;
121
122 event_handler_t* _event_handler = _event_handler_p;
123
124 pthread_mutex_lock(&_event_handler->_mutex);
125
126 push_event(&_event_handler->_events, &_event_handler->_events_count, _func, _arg);
127
128 pthread_mutex_unlock(&_event_handler->_mutex);
129}
130
131int throw_timer_event ( void* _event_handler_p, event_t _func, event_arg_t _arg, uint32_t _timeout)
132{
133 if ( !_func )
134 return FAILURE;
135
136 event_handler_t* _event_handler = _event_handler_p;
137
138 pthread_mutex_lock(&_event_handler->_mutex);
139
140 push_event(&_event_handler->_timed_events, &_event_handler->_timed_events_count, _func, _arg);
141 size_t _counter = _event_handler->_timed_events_count;
142 _event_handler->_timed_events[_counter - 1]._timeout = _timeout + t_time();
143 _event_handler->_timed_events[_counter - 1]._id = _unique_id; ++_unique_id;
144
145
146 /* reorder */
147 if ( _counter > 1 ) {
148
149 int i = _counter - 1;
150 /* start from behind excluding last added member */
151 event_container_t* _it = &_event_handler->_timed_events[i - 1];
152
153 event_container_t _last_added = _event_handler->_timed_events[i];
154
155 for ( ; i > 0; --i ) {
156 if ( _it->_timeout > _timeout ){
157 *(_it + 1) = *_it;
158 *_it = _last_added; -- _it;
159 }
160 }
161
162 }
163
164 pthread_mutex_unlock(&_event_handler->_mutex);
165
166 return _event_handler->_timed_events[_counter - 1]._id;
167}
168int cancel_timer_event ( void* _event_handler_p, int _id )
169{
170 event_handler_t* _event_handler = _event_handler_p;
171 return pop_id(&_event_handler->_timed_events, &_event_handler->_timed_events_count, _id);
172}
173
174event_handler_t* init_event_poll (uint32_t _frequms)
175{
176 event_handler_t* _retu = calloc(sizeof(event_handler_t), 1);
177 assert(_retu);
178 /* Initialize basic events */
179 _retu->_events = NULL ;
180
181 /* Initialize timed events */
182 _retu->_timed_events = NULL;
183
184 _retu->_frequms = _frequms;
185 _retu->_running = 1;
186 pthread_mutex_init(&_retu->_mutex, NULL);
187
188 pthread_create(&_retu->_thread_id, NULL, event_poll, _retu);
189 int _rc = pthread_detach(_retu->_thread_id);
190 assert(_rc == 0);
191
192 return _retu;
193}
194
195int terminate_event_poll(event_handler_t* _handler)
196{
197 if ( !_handler )
198 return FAILURE;
199
200 _handler->_running = 0;
201 while (_handler->_running != -1); /* Wait for execution */
202
203 if (_handler->_events)
204 clear_events(&_handler->_events, &_handler->_events_count);
205 if (_handler->_events)
206 clear_events(&_handler->_timed_events, &_handler->_timed_events_count);
207
208 pthread_mutex_destroy( &_handler->_mutex );
209
210 free(_handler);
211
212 return SUCCESS;
213}
214