diff options
author | Carsten Haitzler (Rasterman) <raster@rasterman.com> | 2013-11-17 11:03:20 +0900 |
---|---|---|
committer | Carsten Haitzler (Rasterman) <raster@rasterman.com> | 2013-11-17 11:03:20 +0900 |
commit | 80d666e7a461c8c76adb01788dc746146bf8ab35 (patch) | |
tree | 66d096cf3fa8fd601ecbe0bbf86b4edb0a998552 | |
parent | 294b05c87479bfe2dbaabf9ba81afd220fa68000 (diff) |
ecore-audio - protect against more list-walking while list is modified
-rw-r--r-- | src/lib/ecore_audio/ecore_audio_obj_out_pulse.c | 50 |
1 files changed, 29 insertions, 21 deletions
diff --git a/src/lib/ecore_audio/ecore_audio_obj_out_pulse.c b/src/lib/ecore_audio/ecore_audio_obj_out_pulse.c index 11fc20f537..ce7bd7f856 100644 --- a/src/lib/ecore_audio/ecore_audio_obj_out_pulse.c +++ b/src/lib/ecore_audio/ecore_audio_obj_out_pulse.c | |||
@@ -214,27 +214,35 @@ static void _input_detach(Eo *eo_obj, void *_pd EINA_UNUSED, va_list *list) | |||
214 | 214 | ||
215 | static void _state_cb(pa_context *context, void *data EINA_UNUSED) | 215 | static void _state_cb(pa_context *context, void *data EINA_UNUSED) |
216 | { | 216 | { |
217 | Eina_List *out; | 217 | Eina_List *out, *tmp; |
218 | Eo *eo_obj; | 218 | Eo *eo_obj; |
219 | pa_context_state_t state; | 219 | pa_context_state_t state; |
220 | 220 | ||
221 | state = pa_context_get_state(context); | 221 | state = pa_context_get_state(context); |
222 | class_vars.state = state; | 222 | class_vars.state = state; |
223 | 223 | ||
224 | if (state == PA_CONTEXT_READY) { | 224 | //ref everything in the list to be sure... |
225 | DBG("PA context ready."); | 225 | EINA_LIST_FOREACH(class_vars.outputs, out, eo_obj) { |
226 | EINA_LIST_FOREACH(class_vars.outputs, out, eo_obj) { | 226 | eo_ref(eo_obj); |
227 | eo_do(eo_obj, eo_event_callback_call(ECORE_AUDIO_EV_OUT_PULSE_CONTEXT_READY, NULL, NULL)); | 227 | } |
228 | } | 228 | // the callback here can delete things in the list.. |
229 | } else if ((state == PA_CONTEXT_FAILED) || (state == PA_CONTEXT_TERMINATED)) { | 229 | if (state == PA_CONTEXT_READY) { |
230 | DBG("PA context fail."); | 230 | DBG("PA context ready."); |
231 | EINA_LIST_FOREACH(class_vars.outputs, out, eo_obj) { | 231 | EINA_LIST_FOREACH(class_vars.outputs, out, eo_obj) { |
232 | eo_do(eo_obj, eo_event_callback_call(ECORE_AUDIO_EV_OUT_PULSE_CONTEXT_FAIL, NULL, NULL)); | 232 | eo_do(eo_obj, eo_event_callback_call(ECORE_AUDIO_EV_OUT_PULSE_CONTEXT_READY, NULL, NULL)); |
233 | } | 233 | } |
234 | } else { | 234 | } else if ((state == PA_CONTEXT_FAILED) || (state == PA_CONTEXT_TERMINATED)) { |
235 | DBG("Connection state %i", state); | 235 | DBG("PA context fail."); |
236 | } | 236 | EINA_LIST_FOREACH(class_vars.outputs, out, eo_obj) { |
237 | 237 | eo_do(eo_obj, eo_event_callback_call(ECORE_AUDIO_EV_OUT_PULSE_CONTEXT_FAIL, NULL, NULL)); | |
238 | } | ||
239 | } else { | ||
240 | DBG("Connection state %i", state); | ||
241 | } | ||
242 | // now unref everything safely | ||
243 | EINA_LIST_FOREACH_SAFE(class_vars.outputs, out, tmp, eo_obj) { | ||
244 | eo_unref(eo_obj); | ||
245 | } | ||
238 | } | 246 | } |
239 | 247 | ||
240 | static void _state_job(void *data EINA_UNUSED) | 248 | static void _state_job(void *data EINA_UNUSED) |