summaryrefslogtreecommitdiff
path: root/src/lib/ecore_audio
diff options
context:
space:
mode:
authorCarsten Haitzler (Rasterman) <raster@rasterman.com>2013-11-17 11:03:20 +0900
committerCarsten Haitzler (Rasterman) <raster@rasterman.com>2013-11-17 11:03:20 +0900
commit80d666e7a461c8c76adb01788dc746146bf8ab35 (patch)
tree66d096cf3fa8fd601ecbe0bbf86b4edb0a998552 /src/lib/ecore_audio
parent294b05c87479bfe2dbaabf9ba81afd220fa68000 (diff)
ecore-audio - protect against more list-walking while list is modified
Diffstat (limited to 'src/lib/ecore_audio')
-rw-r--r--src/lib/ecore_audio/ecore_audio_obj_out_pulse.c50
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
215static void _state_cb(pa_context *context, void *data EINA_UNUSED) 215static 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
240static void _state_job(void *data EINA_UNUSED) 248static void _state_job(void *data EINA_UNUSED)