-/*
- * mlt_events.h -- event handling
- * Copyright (C) 2004-2005 Ushodaya Enterprises Limited
- * Author: Charles Yates <charles.yates@pandora.be>
+/**
+ * \file mlt_events.c
+ * \brief event handling
*
- * 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-2008 Ushodaya Enterprises Limited
+ * \author Charles Yates <charles.yates@pandora.be>
*
- * 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 <stdlib.h>
#include <stdarg.h>
#include <string.h>
+#include <pthread.h>
#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;
typedef struct mlt_events_struct *mlt_events;
+/** \brief Event class
+ *
+ */
+
struct mlt_event_struct
{
mlt_events owner;
};
/** Increment the reference count on this event.
-*/
+ *
+ * \public \memberof mlt_event_struct
+ * \param this an event
+ */
void mlt_event_inc_ref( mlt_event this )
{
- if ( this != NULL && this->owner != NULL )
+ if ( this != NULL )
this->ref_count ++;
}
/** Increment the block count on this event.
-*/
+ *
+ * \public \memberof mlt_event_struct
+ * \param this an event
+ */
void mlt_event_block( mlt_event this )
{
}
/** Decrement the block count on this event.
-*/
+ *
+ * \public \memberof mlt_event_struct
+ * \param this an event
+ */
void mlt_event_unblock( mlt_event this )
{
}
/** Close this event.
-*/
+ *
+ * \public \memberof mlt_event_struct
+ * \param this an event
+ */
void mlt_event_close( mlt_event this )
{
- if ( this != NULL && this->owner != NULL )
+ if ( this != NULL )
{
if ( -- this->ref_count == 1 )
this->owner = NULL;
if ( this->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 );
}
}
}
-/** Forward declaration to private functions.
+/* Forward declaration to private functions.
*/
static mlt_events mlt_events_fetch( mlt_properties );
static void mlt_events_close( mlt_events );
/** Initialise the events structure.
-*/
+ *
+ * \public \memberof mlt_events_struct
+ * \param this a properties list
+ */
void mlt_events_init( mlt_properties this )
{
}
/** Register an event and transmitter.
-*/
+ *
+ * \public \memberof mlt_events_struct
+ * \param this 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 )
{
}
/** Fire an event.
-*/
+ *
+ * This takes a variable number of arguments to supply to the listener.
+
+ * \public \memberof mlt_events_struct
+ * \param this a properties list
+ * \param id the name of an event
+ */
void mlt_events_fire( mlt_properties this, char *id, ... )
{
}
/** Register a listener.
-*/
+ *
+ * \public \memberof mlt_events_struct
+ * \param this 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 )
{
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 this a properties list
+ * \param service an opaque pointer
+ */
void mlt_events_block( mlt_properties this, void *service )
{
}
/** Unblock all events for a given service.
-*/
+ *
+ * \public \memberof mlt_events_struct
+ * \param this a properties list
+ * \param service an opaque pointer
+ */
void mlt_events_unblock( mlt_properties this, void *service )
{
}
/** Disconnect all events for a given service.
-*/
+ *
+ * \public \memberof mlt_events_struct
+ * \param this a properties list
+ * \param service an opaque pointer
+ */
void mlt_events_disconnect( mlt_properties this, void *service )
{
}
}
+/** \brief private to mlt_events_struct, used by mlt_events_wait_for() */
+
+typedef struct
+{
+ int done;
+ pthread_cond_t cond;
+ pthread_mutex_t mutex;
+}
+condition_pair;
+
+/** The event listener callback for the wait functions.
+ *
+ * \private \memberof mlt_events_struct
+ * \param this a properties list
+ * \param pair a condition pair
+ */
+
+static void mlt_events_listen_for( mlt_properties this, condition_pair *pair )
+{
+ pthread_mutex_lock( &pair->mutex );
+ if ( pair->done == 0 )
+ {
+ pthread_cond_signal( &pair->cond );
+ pthread_mutex_unlock( &pair->mutex );
+ }
+}
+
+/** Prepare to wait for an event.
+ *
+ * \public \memberof mlt_events_struct
+ * \param this 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 this, char *id )
+{
+ condition_pair *pair = malloc( sizeof( condition_pair ) );
+ pair->done = 0;
+ pthread_cond_init( &pair->cond, NULL );
+ pthread_mutex_init( &pair->mutex, NULL );
+ pthread_mutex_lock( &pair->mutex );
+ return mlt_events_listen( this, pair, id, ( mlt_listener )mlt_events_listen_for );
+}
+
+/** Wait for an event.
+ *
+ * \public \memberof mlt_events_struct
+ * \param this a properties list
+ * \param event an event
+ */
+
+void mlt_events_wait_for( mlt_properties this, 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 this a properties list
+ * \param event an event
+ */
+
+void mlt_events_close_wait_for( mlt_properties this, mlt_event event )
+{
+ if ( event != NULL )
+ {
+ condition_pair *pair = event->service;
+ event->owner = NULL;
+ pair->done = 0;
+ pthread_mutex_unlock( &pair->mutex );
+ pthread_mutex_destroy( &pair->mutex );
+ pthread_cond_destroy( &pair->cond );
+ }
+}
+
/** Fetch the events object.
-*/
+ *
+ * \private \memberof mlt_events_struct
+ * \param this a properties list
+ * \return an events object
+ */
static mlt_events mlt_events_fetch( mlt_properties this )
{
}
/** Store the events object.
-*/
+ *
+ * \private \memberof mlt_events_struct
+ * \param this a properties list
+ * \param events an events object
+ */
static void mlt_events_store( mlt_properties this, mlt_events events )
{
}
/** Close the events object.
-*/
+ *
+ * \private \memberof mlt_events_struct
+ * \param events an events object
+ */
static void mlt_events_close( mlt_events events )
{
free( events );
}
}
-