From 8d1e6097673f2152fa9f98041610973d3ee6a52a Mon Sep 17 00:00:00 2001 From: Michael Roitzsch Date: Wed, 18 Sep 2002 15:37:11 +0000 Subject: fix reentrant in event listeners by only allowing one event per type CVS patchset: 2689 CVS date: 2002/09/18 15:37:11 --- src/xine-engine/events.c | 36 ++++++++++++++++++++++++++++++------ src/xine-engine/xine.c | 10 ++++++++-- src/xine-engine/xine_internal.h | 6 +++++- 3 files changed, 43 insertions(+), 9 deletions(-) diff --git a/src/xine-engine/events.c b/src/xine-engine/events.c index 0776fcb77..7fefd59e2 100644 --- a/src/xine-engine/events.c +++ b/src/xine-engine/events.c @@ -38,6 +38,7 @@ int xine_register_event_listener (xine_p this_ro, return 0; } + pthread_mutex_lock(&this->event_lock); /* Check we hava a slot free */ if(this->num_event_listeners < XINE_MAX_EVENT_LISTENERS) { @@ -46,28 +47,50 @@ int xine_register_event_listener (xine_p this_ro, this->num_event_listeners++; + pthread_mutex_unlock(&this->event_lock); return 1; } + pthread_mutex_unlock(&this->event_lock); return 0; } void xine_send_event(xine_p this, xine_event_t *event) { uint16_t i; - /* Itterate through all event handlers */ + pthread_mutex_lock(&this->event_lock); + while (this->event_pending[event->type]) + /* there is already one event of that type around */ + pthread_cond_wait(&this->event_handled, &this->event_lock); + this->event_pending[event->type] = 1; + pthread_mutex_unlock(&this->event_lock); + + /* Iterate through all event handlers */ for(i=0; i < this->num_event_listeners; i++) { (this->event_listeners[i]) ((void *)this->event_listener_user_data[i], event); } + + this->event_pending[event->type] = 0; + pthread_cond_signal(&this->event_handled); } int xine_remove_event_listener(xine_p this_ro, xine_event_listener_cb_t listener) { xine_t *this = (xine_t *)this_ro; - uint16_t i, found; - - found = 1; i = 0; - + uint16_t i, found, pending; + + found = 1; + + pthread_mutex_lock(&this->event_lock); + /* wait for any pending events */ + do { + pending = 0; + for (i = 0; i < XINE_MAX_EVENT_TYPES; i++) + pending += this->event_pending[i]; + if (pending) + pthread_cond_wait(&this->event_handled, &this->event_lock); + } while (pending); + /* Attempt to find the listener */ while((found == 1) && (i < this->num_event_listeners)) { if(this->event_listeners[i] == listener) { @@ -82,12 +105,13 @@ int xine_remove_event_listener(xine_p this_ro, this->event_listener_user_data[i] = this->event_listener_user_data[this->num_event_listeners - 1]; this->event_listeners[this->num_event_listeners - 1] = NULL; } - + this->num_event_listeners --; } i++; } + pthread_mutex_unlock(&this->event_lock); return found; } diff --git a/src/xine-engine/xine.c b/src/xine-engine/xine.c index 246c7bccb..54d69de21 100644 --- a/src/xine-engine/xine.c +++ b/src/xine-engine/xine.c @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: xine.c,v 1.159 2002/09/18 00:51:34 guenter Exp $ + * $Id: xine.c,v 1.160 2002/09/18 15:37:11 mroi Exp $ * * top-level xine functions * @@ -649,6 +649,8 @@ void xine_exit (xine_p this_ro) { pthread_mutex_destroy (&this->xine_lock); pthread_mutex_destroy (&this->finished_lock); pthread_mutex_destroy (&this->osd_lock); + pthread_mutex_destroy (&this->event_lock); + pthread_cond_destroy (&this->event_handled); free (this); @@ -683,7 +685,11 @@ xine_p xine_new (void) { pthread_mutex_init (&this->finished_lock, NULL); pthread_mutex_init (&this->osd_lock, NULL); - + + pthread_mutex_init (&this->event_lock, NULL); + + pthread_cond_init (&this->event_handled, NULL); + this->finished_thread_running = 0; /* diff --git a/src/xine-engine/xine_internal.h b/src/xine-engine/xine_internal.h index 40cc188c0..fdb810114 100644 --- a/src/xine-engine/xine_internal.h +++ b/src/xine-engine/xine_internal.h @@ -17,7 +17,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA * - * $Id: xine_internal.h,v 1.101 2002/09/18 06:42:23 jcdutton Exp $ + * $Id: xine_internal.h,v 1.102 2002/09/18 15:37:11 mroi Exp $ * */ @@ -69,6 +69,7 @@ extern "C" { #define VIDEO_DECODER_IFACE_VERSION 10 #define AUDIO_DECODER_IFACE_VERSION 9 #define XINE_MAX_EVENT_LISTENERS 50 +#define XINE_MAX_EVENT_TYPES 100 /* used by plugin loader */ #define XINE_VERSION_CODE XINE_MAJOR_VERSION*10000+XINE_MINOR_VERSION*100+XINE_SUB_VERSION @@ -222,6 +223,9 @@ struct xine_s { xine_event_listener_cb_t event_listeners[XINE_MAX_EVENT_LISTENERS]; void *event_listener_user_data[XINE_MAX_EVENT_LISTENERS]; uint16_t num_event_listeners; + uint8_t event_pending[XINE_MAX_EVENT_TYPES]; + pthread_cond_t event_handled; + pthread_mutex_t event_lock; /* scratch string buffers */ char str[1024]; -- cgit v1.2.3