diff options
author | Martijnvdc <martijnvdc@gmail.com> | 2014-02-01 06:52:48 -0500 |
---|---|---|
committer | Martijnvdc <martijnvdc@gmail.com> | 2014-02-01 06:52:48 -0500 |
commit | 172f18b5e82cb33fcd6d3f56e9052232019fd8c1 (patch) | |
tree | 172faca60c5f1239125e20bcb9986423fbfd580e /toxcore/event.c | |
parent | 984c564cba528328b134578a93a3795a0e0436f3 (diff) |
Added fixes to rtp and updated phone
Diffstat (limited to 'toxcore/event.c')
-rwxr-xr-x | toxcore/event.c | 230 |
1 files changed, 135 insertions, 95 deletions
diff --git a/toxcore/event.c b/toxcore/event.c index 17e68c87..81f8172f 100755 --- a/toxcore/event.c +++ b/toxcore/event.c | |||
@@ -39,11 +39,12 @@ | |||
39 | #include <stddef.h> | 39 | #include <stddef.h> |
40 | #include <inttypes.h> | 40 | #include <inttypes.h> |
41 | #include <pthread.h> | 41 | #include <pthread.h> |
42 | #include <stdio.h> | ||
42 | 43 | ||
43 | #define RUN_IN_THREAD(func, args) { pthread_t _tid; \ | 44 | #define RUN_IN_THREAD(func, args) { pthread_t _tid; \ |
44 | pthread_create(&_tid, NULL, func, args); assert( pthread_detach(_tid) == 0 ); } | 45 | pthread_create(&_tid, NULL, func, args); assert( pthread_detach(_tid) == 0 ); } |
45 | 46 | ||
46 | #define LOCK(event_handler) pthread_mutex_lock (&event_handler->mutex) | 47 | #define LOCK(event_handler) pthread_mutex_lock (&event_handler->mutex) |
47 | #define UNLOCK(event_handler) pthread_mutex_unlock(&event_handler->mutex) | 48 | #define UNLOCK(event_handler) pthread_mutex_unlock(&event_handler->mutex) |
48 | 49 | ||
49 | #define FREQUENCY 10000 | 50 | #define FREQUENCY 10000 |
@@ -52,21 +53,21 @@ | |||
52 | 53 | ||
53 | 54 | ||
54 | typedef struct _EventContainer { | 55 | typedef struct _EventContainer { |
55 | void* (*func)(void*); | 56 | void* (*func)(void*); |
56 | void* func_args; | 57 | void* func_args; |
57 | unsigned timeout; | 58 | unsigned timeout; |
58 | long long id; | 59 | long long id; |
59 | 60 | ||
60 | } EventContainer; | 61 | } EventContainer; |
61 | 62 | ||
62 | typedef struct _EventHandler { | 63 | typedef struct _EventHandler { |
63 | EventContainer* timed_events; | 64 | EventContainer* timed_events; |
64 | size_t timed_events_count; | 65 | size_t timed_events_count; |
65 | 66 | ||
66 | int running; | 67 | int running; |
67 | 68 | ||
68 | pthread_mutex_t mutex; | 69 | pthread_mutex_t mutex; |
69 | 70 | ||
70 | } EventHandler; | 71 | } EventHandler; |
71 | 72 | ||
72 | int throw_event( void* (func)(void*), void* arg ); | 73 | int throw_event( void* (func)(void*), void* arg ); |
@@ -90,7 +91,7 @@ struct _Event event = | |||
90 | void clear_events (EventContainer** event_container, size_t* counter) | 91 | void clear_events (EventContainer** event_container, size_t* counter) |
91 | { | 92 | { |
92 | free(*event_container ); | 93 | free(*event_container ); |
93 | 94 | ||
94 | *event_container = NULL; | 95 | *event_container = NULL; |
95 | *counter = 0; | 96 | *counter = 0; |
96 | } | 97 | } |
@@ -99,62 +100,86 @@ int pop_id ( EventContainer** event_container, size_t* counter, int id ) | |||
99 | { | 100 | { |
100 | if ( !*event_container || !*counter || !id ) | 101 | if ( !*event_container || !*counter || !id ) |
101 | return -1; | 102 | return -1; |
102 | 103 | ||
103 | EventContainer* _it = *event_container; | 104 | EventContainer* _it = *event_container; |
104 | int i; | 105 | int i; |
105 | 106 | ||
106 | for ( i = *counter; i; -- i ){ | 107 | for ( i = *counter; i; -- i ){ |
107 | if ( _it->id == id ) { /* Hit! */ | 108 | if ( _it->id == id ) { /* Hit! */ |
108 | break; | 109 | break; |
109 | } | 110 | } |
110 | ++_it; | 111 | ++_it; |
111 | } | 112 | } |
112 | 113 | ||
113 | if ( i ) { | 114 | if ( i ) { |
114 | for ( ; i; -- i ){ *_it = *(_it + 1); ++_it; } | 115 | for ( ; i; -- i ){ *_it = *(_it + 1); ++_it; } |
115 | -- (*counter ); | 116 | -- (*counter ); |
116 | *event_container = realloc(*event_container, sizeof(EventContainer) * (*counter )); /* resize */ | 117 | |
117 | 118 | if ( !(*counter)) { /* Free and set to NULL */ | |
118 | return 0; | 119 | free(*event_container); |
119 | 120 | *event_container = NULL; | |
121 | } | ||
122 | else { | ||
123 | void* _result = realloc(*event_container, sizeof(EventContainer) * (*counter )); /* resize */ | ||
124 | |||
125 | |||
126 | if ( _result != NULL ) { *event_container = _result; return 0; } | ||
127 | else { | ||
128 | /* Not sure what would happen next so abort execution. | ||
129 | */ | ||
130 | fprintf(stderr, "CRITICAL! Failed to reallocate memory in %s():%d, aborting...", __func__, __LINE__); | ||
131 | abort(); | ||
132 | return -1; | ||
133 | } | ||
134 | } | ||
120 | } | 135 | } |
121 | 136 | ||
122 | /* not found here */ | 137 | /* not found here */ |
123 | 138 | ||
124 | return -1; | 139 | return -1; |
125 | } | 140 | } |
126 | 141 | ||
127 | void push_event ( EventContainer** container, size_t* counter, void* (func)(void*), void* arg ) | 142 | void push_event ( EventContainer** container, size_t* counter, void* (func)(void*), void* arg ) |
128 | { | 143 | { |
129 | (*container ) = realloc((*container ), sizeof(EventContainer) * ((*counter ) + 1)); | 144 | EventContainer* _new = realloc((*container ), sizeof(EventContainer) * ((*counter ) + 1)); |
130 | assert((*container ) != NULL); | 145 | |
131 | 146 | if ( _new == NULL ) { | |
132 | (*container )[*counter].func = func; | 147 | /* Not sure what would happen next so abort execution. |
133 | (*container )[*counter].func_args = arg; | 148 | * TODO: This could notice the calling function |
134 | (*container )[*counter].timeout = 0; | 149 | * about realloc failing. |
135 | (*container )[*counter].id = 0; | 150 | */ |
136 | 151 | fprintf(stderr, "CRITICAL! Failed to reallocate memory in %s():%d, aborting...", __func__, __LINE__); | |
152 | abort(); | ||
153 | } | ||
154 | |||
155 | _new[*counter].func = func; | ||
156 | _new[*counter].func_args = arg; | ||
157 | _new[*counter].timeout = 0; | ||
158 | _new[*counter].id = 0; | ||
159 | |||
160 | (*container) = _new; | ||
161 | |||
137 | (*counter )++; | 162 | (*counter )++; |
138 | } | 163 | } |
139 | 164 | ||
140 | void reorder_events ( size_t counter, EventContainer* container, unsigned timeout ) | 165 | void reorder_events ( size_t counter, EventContainer* container, unsigned timeout ) |
141 | { | 166 | { |
142 | if ( counter > 1 ) { | 167 | if ( counter > 1 ) { |
143 | 168 | ||
144 | int i = counter - 1; | 169 | int i = counter - 1; |
145 | 170 | ||
146 | /* start from behind excluding last added member */ | 171 | /* start from behind excluding last added member */ |
147 | EventContainer* _it = &container[i - 1]; | 172 | EventContainer* _it = &container[i - 1]; |
148 | 173 | ||
149 | EventContainer _last_added = container[i]; | 174 | EventContainer _last_added = container[i]; |
150 | 175 | ||
151 | for ( ; i; --i ) { | 176 | for ( ; i; --i ) { |
152 | if ( _it->timeout > timeout ){ | 177 | if ( _it->timeout > timeout ){ |
153 | *(_it + 1) = *_it; | 178 | *(_it + 1) = *_it; |
154 | *_it = _last_added; -- _it; | 179 | *_it = _last_added; -- _it; |
155 | } | 180 | } |
156 | } | 181 | } |
157 | 182 | ||
158 | } | 183 | } |
159 | } | 184 | } |
160 | 185 | ||
@@ -164,40 +189,40 @@ void reorder_events ( size_t counter, EventContainer* container, unsigned timeou | |||
164 | void* event_poll( void* arg ) | 189 | void* event_poll( void* arg ) |
165 | { | 190 | { |
166 | EventHandler* _event_handler = arg; | 191 | EventHandler* _event_handler = arg; |
167 | 192 | ||
168 | while ( _event_handler->running ) | 193 | while ( _event_handler->running ) |
169 | { | 194 | { |
170 | 195 | ||
171 | LOCK( _event_handler ); | 196 | LOCK( _event_handler ); |
172 | 197 | ||
173 | if ( _event_handler->timed_events ){ | 198 | if ( _event_handler->timed_events ){ |
174 | 199 | ||
175 | uint32_t _time = ((uint32_t)(current_time() / 1000)); | 200 | uint32_t _time = ((uint32_t)(current_time() / 1000)); |
176 | 201 | ||
177 | if ( _event_handler->timed_events[0].timeout < _time ) { | 202 | if ( _event_handler->timed_events[0].timeout < _time ) { |
178 | 203 | ||
179 | RUN_IN_THREAD ( _event_handler->timed_events[0].func, | 204 | RUN_IN_THREAD ( _event_handler->timed_events[0].func, |
180 | _event_handler->timed_events[0].func_args ); | 205 | _event_handler->timed_events[0].func_args ); |
181 | 206 | ||
182 | pop_id(&_event_handler->timed_events, | 207 | pop_id(&_event_handler->timed_events, |
183 | &_event_handler->timed_events_count, | 208 | &_event_handler->timed_events_count, |
184 | _event_handler->timed_events[0].id); | 209 | _event_handler->timed_events[0].id); |
185 | 210 | ||
186 | } | 211 | } |
187 | 212 | ||
188 | } | 213 | } |
189 | 214 | ||
190 | UNLOCK( _event_handler ); | 215 | UNLOCK( _event_handler ); |
191 | 216 | ||
192 | usleep(FREQUENCY); | 217 | usleep(FREQUENCY); |
193 | } | 218 | } |
194 | 219 | ||
195 | LOCK( _event_handler ); | 220 | LOCK( _event_handler ); |
196 | 221 | ||
197 | clear_events(&_event_handler->timed_events, &_event_handler->timed_events_count); | 222 | clear_events(&_event_handler->timed_events, &_event_handler->timed_events_count); |
198 | 223 | ||
199 | UNLOCK( _event_handler ); | 224 | UNLOCK( _event_handler ); |
200 | 225 | ||
201 | _event_handler->running = -1; | 226 | _event_handler->running = -1; |
202 | pthread_exit(NULL); | 227 | pthread_exit(NULL); |
203 | } | 228 | } |
@@ -207,7 +232,7 @@ int throw_event( void* (func)(void*), void* arg ) | |||
207 | pthread_t _tid; | 232 | pthread_t _tid; |
208 | int _rc = | 233 | int _rc = |
209 | pthread_create(&_tid, NULL, func, arg ); | 234 | pthread_create(&_tid, NULL, func, arg ); |
210 | 235 | ||
211 | return (0 != _rc ) ? _rc : pthread_detach(_tid); | 236 | return (0 != _rc ) ? _rc : pthread_detach(_tid); |
212 | } | 237 | } |
213 | 238 | ||
@@ -217,31 +242,31 @@ EventHandler event_handler; | |||
217 | int throw_timer_event ( void* (func)(void*), void* arg, unsigned timeout) | 242 | int throw_timer_event ( void* (func)(void*), void* arg, unsigned timeout) |
218 | { | 243 | { |
219 | static int _unique_id = 1; | 244 | static int _unique_id = 1; |
220 | 245 | ||
221 | push_event(&event_handler.timed_events, &(event_handler.timed_events_count), func, arg ); | 246 | push_event(&event_handler.timed_events, &(event_handler.timed_events_count), func, arg ); |
222 | 247 | ||
223 | size_t _counter = event_handler.timed_events_count; | 248 | size_t _counter = event_handler.timed_events_count; |
224 | 249 | ||
225 | event_handler.timed_events[_counter - 1].timeout = timeout + ((uint32_t)(current_time() / 1000)); | 250 | event_handler.timed_events[_counter - 1].timeout = timeout + ((uint32_t)(current_time() / 1000)); |
226 | event_handler.timed_events[_counter - 1].id = _unique_id; ++_unique_id; | 251 | event_handler.timed_events[_counter - 1].id = _unique_id; ++_unique_id; |
227 | 252 | ||
228 | 253 | ||
229 | /* reorder */ | 254 | /* reorder */ |
230 | 255 | ||
231 | reorder_events(_counter, event_handler.timed_events, timeout ); | 256 | reorder_events(_counter, event_handler.timed_events, timeout ); |
232 | 257 | ||
233 | return _unique_id - 1; | 258 | return _unique_id - 1; |
234 | } | 259 | } |
235 | 260 | ||
236 | int execute_timer_event ( int id ) | 261 | int execute_timer_event ( int id ) |
237 | { | 262 | { |
238 | int _status; | 263 | int _status; |
239 | 264 | ||
240 | LOCK((&event_handler)); | 265 | LOCK((&event_handler)); |
241 | EventContainer* _it = event_handler.timed_events; | 266 | EventContainer* _it = event_handler.timed_events; |
242 | 267 | ||
243 | int _i = event_handler.timed_events_count; | 268 | int _i = event_handler.timed_events_count; |
244 | 269 | ||
245 | /* Find it and execute */ | 270 | /* Find it and execute */ |
246 | for ( ; _i; _i-- ) { | 271 | for ( ; _i; _i-- ) { |
247 | if ( _it->id == id ) { | 272 | if ( _it->id == id ) { |
@@ -250,36 +275,51 @@ LOCK((&event_handler)); | |||
250 | } | 275 | } |
251 | ++_it; | 276 | ++_it; |
252 | } | 277 | } |
253 | 278 | ||
254 | /* Now remove it from the queue */ | 279 | /* Now remove it from the queue */ |
255 | 280 | ||
256 | if ( _i ) { | 281 | if ( _i ) { |
257 | for ( ; _i; -- _i ){ *_it = *(_it + 1); ++_it; } | 282 | for ( ; _i; -- _i ){ *_it = *(_it + 1); ++_it; } |
283 | |||
258 | -- event_handler.timed_events_count; | 284 | -- event_handler.timed_events_count; |
259 | 285 | ||
260 | event_handler.timed_events = realloc | 286 | if ( !event_handler.timed_events_count ) { /* Free and set to null */ |
261 | (event_handler.timed_events, sizeof(EventContainer) * event_handler.timed_events_count); /* resize */ | 287 | free(event_handler.timed_events); |
262 | 288 | event_handler.timed_events = NULL; | |
289 | } | ||
290 | else { | ||
291 | void* _result = realloc(event_handler.timed_events, sizeof(EventContainer) * event_handler.timed_events_count); /* resize */ | ||
292 | |||
293 | if ( _result != NULL ) { event_handler.timed_events = _result; } | ||
294 | else { | ||
295 | /* Not sure what would happen next so abort execution. | ||
296 | */ | ||
297 | fprintf(stderr, "CRITICAL! Failed to reallocate memory in %s():%d, aborting...", __func__, __LINE__); | ||
298 | abort(); | ||
299 | return -1; | ||
300 | } | ||
301 | } | ||
302 | |||
263 | _status = 0; | 303 | _status = 0; |
264 | 304 | ||
265 | } | 305 | } |
266 | else _status = -1; | 306 | else _status = -1; |
267 | 307 | ||
268 | UNLOCK((&event_handler)); | 308 | UNLOCK((&event_handler)); |
269 | 309 | ||
270 | return _status; | 310 | return _status; |
271 | } | 311 | } |
272 | 312 | ||
273 | int reset_timer_event ( int id, uint32_t timeout ) | 313 | int reset_timer_event ( int id, uint32_t timeout ) |
274 | { | 314 | { |
275 | int _status; | 315 | int _status; |
276 | 316 | ||
277 | LOCK((&event_handler)); | 317 | LOCK((&event_handler)); |
278 | 318 | ||
279 | EventContainer* _it = event_handler.timed_events; | 319 | EventContainer* _it = event_handler.timed_events; |
280 | 320 | ||
281 | int _i = event_handler.timed_events_count; | 321 | int _i = event_handler.timed_events_count; |
282 | 322 | ||
283 | /* Find it and change */ | 323 | /* Find it and change */ |
284 | for ( ; _i; _i-- ) { | 324 | for ( ; _i; _i-- ) { |
285 | if ( _it->id == id ) { | 325 | if ( _it->id == id ) { |
@@ -288,11 +328,11 @@ LOCK((&event_handler)); | |||
288 | } | 328 | } |
289 | ++_it; | 329 | ++_it; |
290 | } | 330 | } |
291 | 331 | ||
292 | _status = _i ? -1 : 0; | 332 | _status = _i ? -1 : 0; |
293 | 333 | ||
294 | UNLOCK((&event_handler)); | 334 | UNLOCK((&event_handler)); |
295 | 335 | ||
296 | return _status; | 336 | return _status; |
297 | } | 337 | } |
298 | 338 | ||
@@ -312,11 +352,11 @@ void __attribute__((constructor)) init_event_poll () | |||
312 | { | 352 | { |
313 | event_handler.timed_events = NULL; | 353 | event_handler.timed_events = NULL; |
314 | event_handler.timed_events_count = 0; | 354 | event_handler.timed_events_count = 0; |
315 | 355 | ||
316 | event_handler.running = 1; | 356 | event_handler.running = 1; |
317 | 357 | ||
318 | pthread_mutex_init(&event_handler.mutex, NULL); | 358 | pthread_mutex_init(&event_handler.mutex, NULL); |
319 | 359 | ||
320 | RUN_IN_THREAD(event_poll, &event_handler); | 360 | RUN_IN_THREAD(event_poll, &event_handler); |
321 | } | 361 | } |
322 | 362 | ||
@@ -326,10 +366,10 @@ void __attribute__((destructor)) terminate_event_poll() | |||
326 | event_handler.running = 0; | 366 | event_handler.running = 0; |
327 | 367 | ||
328 | /* Keep the global until thread exits */ | 368 | /* Keep the global until thread exits */ |
329 | while (event_handler.running > -1) { | 369 | while (event_handler.running > -1) { |
330 | event_handler.running; | 370 | (void)event_handler.running; |
331 | usleep(FREQUENCY*2); | 371 | usleep(FREQUENCY*2); |
332 | } | 372 | } |
333 | 373 | ||
334 | pthread_mutex_destroy( &event_handler.mutex ); | 374 | pthread_mutex_destroy( &event_handler.mutex ); |
335 | } | 375 | } \ No newline at end of file |