X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Fframework%2Fmlt_events.c;h=2a9f01530681a4d7b8632ba3d9f61e0e4d892779;hb=fb83cd55e7111826cc45ede380198daaff7ac60f;hp=e42dabb1cfd9b15aafe250dfc355575f2262705b;hpb=909d149697331a560edb1924f58fc58c5a25aaea;p=mlt diff --git a/src/framework/mlt_events.c b/src/framework/mlt_events.c index e42dabb1..2a9f0153 100644 --- a/src/framework/mlt_events.c +++ b/src/framework/mlt_events.c @@ -1,40 +1,51 @@ -/* - * mlt_events.h -- event handling - * Copyright (C) 2004-2005 Ushodaya Enterprises Limited - * Author: Charles Yates +/** + * \file mlt_events.c + * \brief event handling + * \see mlt_events_struct * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * Copyright (C) 2004-2009 Ushodaya Enterprises Limited + * \author Charles Yates * - * This program is distributed in the hope that it will be useful, + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software Foundation, - * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include +#include #include "mlt_properties.h" #include "mlt_events.h" -/** Memory leak checks. -*/ +/* Memory leak checks. */ -//#define _MLT_EVENT_CHECKS_ +#undef _MLT_EVENT_CHECKS_ #ifdef _MLT_EVENT_CHECKS_ static int events_created = 0; static int events_destroyed = 0; #endif +/** \brief Events class + * + * Events provide messages and notifications between services and the application. + * A service can register an event and fire/send it upon certain conditions or times. + * Likewise, a service or an application can listen/receive specific events on specific + * services. + */ + struct mlt_events_struct { mlt_properties owner; @@ -43,6 +54,10 @@ struct mlt_events_struct typedef struct mlt_events_struct *mlt_events; +/** \brief Event class + * + */ + struct mlt_event_struct { mlt_events owner; @@ -52,54 +67,65 @@ struct mlt_event_struct void *service; }; -/** Increment the reference count on this event. -*/ +/** Increment the reference count on self event. + * + * \public \memberof mlt_event_struct + * \param self an event + */ -void mlt_event_inc_ref( mlt_event this ) +void mlt_event_inc_ref( mlt_event self ) { - if ( this != NULL && this->owner != NULL ) - this->ref_count ++; + if ( self != NULL ) + self->ref_count ++; } -/** Increment the block count on this event. -*/ +/** Increment the block count on self event. + * + * \public \memberof mlt_event_struct + * \param self an event + */ -void mlt_event_block( mlt_event this ) +void mlt_event_block( mlt_event self ) { - if ( this != NULL && this->owner != NULL ) - this->block_count ++; + if ( self != NULL && self->owner != NULL ) + self->block_count ++; } -/** Decrement the block count on this event. -*/ +/** Decrement the block count on self event. + * + * \public \memberof mlt_event_struct + * \param self an event + */ -void mlt_event_unblock( mlt_event this ) +void mlt_event_unblock( mlt_event self ) { - if ( this != NULL && this->owner != NULL ) - this->block_count --; + if ( self != NULL && self->owner != NULL ) + self->block_count --; } -/** Close this event. -*/ +/** Close self event. + * + * \public \memberof mlt_event_struct + * \param self an event + */ -void mlt_event_close( mlt_event this ) +void mlt_event_close( mlt_event self ) { - if ( this != NULL && this->owner != NULL ) + if ( self != NULL ) { - if ( -- this->ref_count == 1 ) - this->owner = NULL; - if ( this->ref_count <= 0 ) + if ( -- self->ref_count == 1 ) + self->owner = NULL; + if ( self->ref_count <= 0 ) { #ifdef _MLT_EVENT_CHECKS_ - events_destroyed ++; - fprintf( stderr, "Events created %d, destroyed %d\n", events_created, events_destroyed ); + mlt_log( NULL, MLT_LOG_DEBUG, "Events created %d, destroyed %d\n", events_created, ++events_destroyed ); #endif - free( this ); + free( self ); } } } -/** Forward declaration to private functions. +/* Forward declaration to private functions. */ static mlt_events mlt_events_fetch( mlt_properties ); @@ -107,26 +133,35 @@ static void mlt_events_store( mlt_properties, mlt_events ); static void mlt_events_close( mlt_events ); /** Initialise the events structure. -*/ + * + * \public \memberof mlt_events_struct + * \param self a properties list + */ -void mlt_events_init( mlt_properties this ) +void mlt_events_init( mlt_properties self ) { - mlt_events events = mlt_events_fetch( this ); + mlt_events events = mlt_events_fetch( self ); if ( events == NULL ) { - events = malloc( sizeof( struct mlt_events_struct ) ); + events = calloc( 1, sizeof( struct mlt_events_struct ) ); events->list = mlt_properties_new( ); - mlt_events_store( this, events ); + mlt_events_store( self, events ); } } /** Register an event and transmitter. -*/ + * + * \public \memberof mlt_events_struct + * \param self a properties list + * \param id the name of an event + * \param transmitter the callback function to send an event message + * \return true if there was an error + */ -int mlt_events_register( mlt_properties this, char *id, mlt_transmitter transmitter ) +int mlt_events_register( mlt_properties self, const char *id, mlt_transmitter transmitter ) { int error = 1; - mlt_events events = mlt_events_fetch( this ); + mlt_events events = mlt_events_fetch( self ); if ( events != NULL ) { mlt_properties list = events->list; @@ -140,11 +175,17 @@ int mlt_events_register( mlt_properties this, char *id, mlt_transmitter transmit } /** Fire an event. -*/ + * + * This takes a variable number of arguments to supply to the listener. + + * \public \memberof mlt_events_struct + * \param self a properties list + * \param id the name of an event + */ -void mlt_events_fire( mlt_properties this, char *id, ... ) +void mlt_events_fire( mlt_properties self, const char *id, ... ) { - mlt_events events = mlt_events_fetch( this ); + mlt_events events = mlt_events_fetch( self ); if ( events != NULL ) { int i = 0; @@ -181,12 +222,19 @@ void mlt_events_fire( mlt_properties this, char *id, ... ) } /** Register a listener. -*/ + * + * \public \memberof mlt_events_struct + * \param self a properties list + * \param service an opaque pointer + * \param id the name of the event to listen for + * \param listener the callback to receive an event message + * \return + */ -mlt_event mlt_events_listen( mlt_properties this, void *service, char *id, mlt_listener listener ) +mlt_event mlt_events_listen( mlt_properties self, void *service, const char *id, mlt_listener listener ) { mlt_event event = NULL; - mlt_events events = mlt_events_fetch( this ); + mlt_events events = mlt_events_fetch( self ); if ( events != NULL ) { mlt_properties list = events->list; @@ -227,22 +275,25 @@ mlt_event mlt_events_listen( mlt_properties this, void *service, char *id, mlt_l event->listener = listener; event->service = service; mlt_properties_set_data( listeners, temp, event, 0, ( mlt_destructor )mlt_event_close, NULL ); + mlt_event_inc_ref( event ); } } - if ( event != NULL ) - mlt_event_inc_ref( event ); } } return event; } /** Block all events for a given service. -*/ + * + * \public \memberof mlt_events_struct + * \param self a properties list + * \param service an opaque pointer + */ -void mlt_events_block( mlt_properties this, void *service ) +void mlt_events_block( mlt_properties self, void *service ) { - mlt_events events = mlt_events_fetch( this ); + mlt_events events = mlt_events_fetch( self ); if ( events != NULL ) { int i = 0, j = 0; @@ -265,11 +316,15 @@ void mlt_events_block( mlt_properties this, void *service ) } /** Unblock all events for a given service. -*/ + * + * \public \memberof mlt_events_struct + * \param self a properties list + * \param service an opaque pointer + */ -void mlt_events_unblock( mlt_properties this, void *service ) +void mlt_events_unblock( mlt_properties self, void *service ) { - mlt_events events = mlt_events_fetch( this ); + mlt_events events = mlt_events_fetch( self ); if ( events != NULL ) { int i = 0, j = 0; @@ -292,11 +347,15 @@ void mlt_events_unblock( mlt_properties this, void *service ) } /** Disconnect all events for a given service. -*/ + * + * \public \memberof mlt_events_struct + * \param self a properties list + * \param service an opaque pointer + */ -void mlt_events_disconnect( mlt_properties this, void *service ) +void mlt_events_disconnect( mlt_properties self, void *service ) { - mlt_events events = mlt_events_fetch( this ); + mlt_events events = mlt_events_fetch( self ); if ( events != NULL ) { int i = 0, j = 0; @@ -319,28 +378,115 @@ void mlt_events_disconnect( mlt_properties this, void *service ) } } +/** \brief private to mlt_events_struct, used by mlt_events_wait_for() */ + +typedef struct +{ + pthread_cond_t cond; + pthread_mutex_t mutex; +} +condition_pair; + +/** The event listener callback for the wait functions. + * + * \private \memberof mlt_events_struct + * \param self a properties list + * \param pair a condition pair + */ + +static void mlt_events_listen_for( mlt_properties self, condition_pair *pair ) +{ + pthread_mutex_lock( &pair->mutex ); + pthread_cond_signal( &pair->cond ); + pthread_mutex_unlock( &pair->mutex ); +} + +/** Prepare to wait for an event. + * + * \public \memberof mlt_events_struct + * \param self a properties list + * \param id the name of the event to wait for + * \return an event + */ + +mlt_event mlt_events_setup_wait_for( mlt_properties self, const char *id ) +{ + condition_pair *pair = malloc( sizeof( condition_pair ) ); + pthread_cond_init( &pair->cond, NULL ); + pthread_mutex_init( &pair->mutex, NULL ); + pthread_mutex_lock( &pair->mutex ); + return mlt_events_listen( self, pair, id, ( mlt_listener )mlt_events_listen_for ); +} + +/** Wait for an event. + * + * \public \memberof mlt_events_struct + * \param self a properties list + * \param event an event + */ + +void mlt_events_wait_for( mlt_properties self, mlt_event event ) +{ + if ( event != NULL ) + { + condition_pair *pair = event->service; + pthread_cond_wait( &pair->cond, &pair->mutex ); + } +} + +/** Cleanup after waiting for an event. + * + * \public \memberof mlt_events_struct + * \param self a properties list + * \param event an event + */ + +void mlt_events_close_wait_for( mlt_properties self, mlt_event event ) +{ + if ( event != NULL ) + { + condition_pair *pair = event->service; + event->owner = NULL; + pthread_mutex_unlock( &pair->mutex ); + pthread_mutex_destroy( &pair->mutex ); + pthread_cond_destroy( &pair->cond ); + free( pair ); + } +} + /** Fetch the events object. -*/ + * + * \private \memberof mlt_events_struct + * \param self a properties list + * \return an events object + */ -static mlt_events mlt_events_fetch( mlt_properties this ) +static mlt_events mlt_events_fetch( mlt_properties self ) { mlt_events events = NULL; - if ( this != NULL ) - events = mlt_properties_get_data( this, "_events", NULL ); + if ( self != NULL ) + events = mlt_properties_get_data( self, "_events", NULL ); return events; } /** Store the events object. -*/ + * + * \private \memberof mlt_events_struct + * \param self a properties list + * \param events an events object + */ -static void mlt_events_store( mlt_properties this, mlt_events events ) +static void mlt_events_store( mlt_properties self, mlt_events events ) { - if ( this != NULL && events != NULL ) - mlt_properties_set_data( this, "_events", events, 0, ( mlt_destructor )mlt_events_close, NULL ); + if ( self != NULL && events != NULL ) + mlt_properties_set_data( self, "_events", events, 0, ( mlt_destructor )mlt_events_close, NULL ); } /** Close the events object. -*/ + * + * \private \memberof mlt_events_struct + * \param events an events object + */ static void mlt_events_close( mlt_events events ) { @@ -350,4 +496,3 @@ static void mlt_events_close( mlt_events events ) free( events ); } } -