diff options
Diffstat (limited to 'toxmsi/toxmsi_event.c')
-rw-r--r-- | toxmsi/toxmsi_event.c | 214 |
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 | |||
15 | static int _unique_id = 1; | ||
16 | |||
17 | /* clear events */ | ||
18 | void 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 | |||
28 | int 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 */ | ||
60 | void* 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 | |||
105 | void 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 | |||
117 | void 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 | |||
131 | int 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 | } | ||
168 | int 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 | |||
174 | event_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 | |||
195 | int 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 | |||