X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Fcontrol%2Fevent_async.c;h=ecb6fa8890e8259c0b9fa94dcc3c1f71efd9b322;hb=a537329058d5700fe37344fa36c24e02bb89f289;hp=147e87bc2eee4901baf33970a98c32e2ecb09ab9;hpb=b87119655e83360e92ec8439a5193a9dad68638d;p=vlc diff --git a/src/control/event_async.c b/src/control/event_async.c index 147e87bc2e..ecb6fa8890 100644 --- a/src/control/event_async.c +++ b/src/control/event_async.c @@ -22,6 +22,10 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. *****************************************************************************/ +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + #include #include @@ -73,12 +77,12 @@ static void push(libvlc_event_manager_t * p_em, libvlc_event_listener_t * listen static const long MaxQueuedItem = 300000; long count = 0; #endif - + struct queue_elmt * elmt = malloc(sizeof(struct queue_elmt)); elmt->listener = *listener; elmt->event = *event; elmt->next = NULL; - + /* Append to the end of the queue */ struct queue_elmt * iter = queue(p_em)->elements; if(!iter) @@ -118,7 +122,7 @@ static bool pop(libvlc_event_manager_t * p_em, libvlc_event_listener_t * listene *listener = queue(p_em)->elements->listener; *event = queue(p_em)->elements->event; - + struct queue_elmt * elmt = queue(p_em)->elements; queue(p_em)->elements = elmt->next; free(elmt); @@ -133,14 +137,18 @@ static void pop_listener(libvlc_event_manager_t * p_em, libvlc_event_listener_t while (iter) { if(listeners_are_equal(&iter->listener, listener)) { + struct queue_elmt * to_delete = iter; if(!prev) - queue(p_em)->elements = iter->next; + queue(p_em)->elements = to_delete->next; else - prev->next = iter->next; - free(iter); + prev->next = to_delete->next; + iter = to_delete->next; + free(to_delete); + } + else { + prev = iter; + iter = iter->next; } - prev = iter; - iter = iter->next; } } @@ -151,9 +159,15 @@ static void pop_listener(libvlc_event_manager_t * p_em, libvlc_event_listener_t **************************************************************************/ void libvlc_event_async_fini(libvlc_event_manager_t * p_em) -{ +{ if(!is_queue_initialized(p_em)) return; - + + if(current_thread_is_asynch_thread(p_em)) + { + fprintf(stderr, "*** Error: releasing the last reference of the observed object from its callback thread is not (yet!) supported\n"); + abort(); + } + vlc_thread_t thread = queue(p_em)->thread; if(thread) { @@ -172,7 +186,7 @@ libvlc_event_async_fini(libvlc_event_manager_t * p_em) iter = iter->next; free(elemt_to_delete); } - + free(queue(p_em)); } @@ -186,7 +200,14 @@ libvlc_event_async_init(libvlc_event_manager_t * p_em) { p_em->async_event_queue = calloc(1, sizeof(struct libvlc_event_async_queue)); - int error = vlc_clone (&queue(p_em)->thread, event_async_loop, p_em, VLC_THREAD_PRIORITY_LOW); + int error = vlc_threadvar_create(&queue(p_em)->is_asynch_dispatch_thread_var, NULL); + assert(!error); + + vlc_mutex_init(&queue(p_em)->lock); + vlc_cond_init(&queue(p_em)->signal); + vlc_cond_init(&queue(p_em)->signal_idle); + + error = vlc_clone (&queue(p_em)->thread, event_async_loop, p_em, VLC_THREAD_PRIORITY_LOW); if(error) { free(p_em->async_event_queue); @@ -194,11 +215,6 @@ libvlc_event_async_init(libvlc_event_manager_t * p_em) return; } - vlc_mutex_init(&queue(p_em)->lock); - vlc_cond_init(&queue(p_em)->signal); - vlc_cond_init(&queue(p_em)->signal_idle); - error = vlc_threadvar_create(&queue(p_em)->is_asynch_dispatch_thread_var, NULL); - assert(!error); } /************************************************************************** @@ -213,7 +229,7 @@ libvlc_event_async_ensure_listener_removal(libvlc_event_manager_t * p_em, libvlc queue_lock(p_em); pop_listener(p_em, listener); - + // Wait for the asynch_loop to have processed all events. if(!current_thread_is_asynch_thread(p_em)) { @@ -254,7 +270,7 @@ static void * event_async_loop(void * arg) libvlc_event_listener_t listener; libvlc_event_t event; - vlc_threadvar_set(queue(p_em)->is_asynch_dispatch_thread_var, (void*)true); + vlc_threadvar_set(queue(p_em)->is_asynch_dispatch_thread_var, p_em); queue_lock(p_em); while (true) { @@ -274,7 +290,7 @@ static void * event_async_loop(void * arg) vlc_cond_broadcast(&queue(p_em)->signal_idle); // We'll be idle vlc_cond_wait(&queue(p_em)->signal, &queue(p_em)->lock); vlc_cleanup_pop(); - + queue(p_em)->is_idle = false; } }