Exemplo n.º 1
0
void mlt_cache_purge( mlt_cache cache, void *object )
{
	if (!cache) return;
	pthread_mutex_lock( &cache->mutex );
	if ( cache && object )
	{
		int i, j;
		void **alt = cache->current == cache->A ? cache->B : cache->A;

		for ( i = 0, j = 0; i < cache->count; i++ )
		{
			void *o = cache->current[ i ];

			if ( o == object )
			{
				cache_object_close( cache, o, NULL );
			}
			else
			{
				alt[ j++ ] = o;
			}
		}
		cache->count = j;
		cache->current = alt;
	}
	pthread_mutex_unlock( &cache->mutex );
}
Exemplo n.º 2
0
void mlt_cache_item_close( mlt_cache_item item )
{
	if ( item )
	{
		pthread_mutex_lock( &item->cache->mutex );
		cache_object_close( item->cache, item->object, item->data );
		pthread_mutex_unlock( &item->cache->mutex );
	}
}
Exemplo n.º 3
0
Arquivo: mlt_cache.c Projeto: rayl/MLT
void mlt_cache_purge( mlt_cache cache, void *object )
{
    pthread_mutex_lock( &cache->mutex );
    if ( cache && object )
    {
        int i, j;
        void **alt = cache->current == cache->A ? cache->B : cache->A;

        for ( i = 0, j = 0; i < cache->count; i++ )
        {
            void *o = cache->current[ i ];

            if ( o == object )
            {
                pthread_mutex_unlock( &cache->mutex );
                cache_object_close( cache, o, NULL );
                pthread_mutex_lock( &cache->mutex );
            }
            else
            {
                alt[ j++ ] = o;
            }
        }
        cache->count = j;
        cache->current = alt;

        // Remove the object's data from the active list regardless of refcount
        char key[19];
        sprintf( key, "%p", object );
        mlt_cache_item item = mlt_properties_get_data( cache->active, key, NULL );
        if ( item && item->destructor )
        {
            item->destructor( item->data );
            item->data = NULL;
            item->destructor = NULL;
            mlt_properties_set_data( cache->active, key, NULL, 0, NULL, NULL );
        }

        // Remove the object's items from the garbage collection regardless of refcount
        i = mlt_properties_count( cache->garbage );
        while ( i-- )
        {
            item = mlt_properties_get_data_at( cache->garbage, i, NULL );
            if ( object == item->object && item->destructor )
            {
                sprintf( key, "%p", item->data );
                item->destructor( item->data );
                item->data = NULL;
                item->destructor = NULL;
                mlt_properties_set_data( cache->garbage, key, NULL, 0, NULL, NULL );
            }
        }
    }
    pthread_mutex_unlock( &cache->mutex );
}
Exemplo n.º 4
0
Arquivo: mlt_cache.c Projeto: rayl/MLT
void mlt_cache_close( mlt_cache cache )
{
    if ( cache )
    {
        while ( cache->count-- )
        {
            void *object = cache->current[ cache->count ];
            mlt_log( NULL, MLT_LOG_DEBUG, "%s: %d = %p\n", __FUNCTION__, cache->count, object );
            cache_object_close( cache, object, NULL );
        }
        mlt_properties_close( cache->active );
        mlt_properties_close( cache->garbage );
        pthread_mutex_destroy( &cache->mutex );
        free( cache );
    }
}
Exemplo n.º 5
0
Arquivo: mlt_cache.c Projeto: rayl/MLT
void mlt_cache_put( mlt_cache cache, void *object, void* data, int size, mlt_destructor destructor )
{
    pthread_mutex_lock( &cache->mutex );
    void **hit = shuffle_get_hit( cache, object );
    void **alt = cache->current == cache->A ? cache->B : cache->A;

    // add the object to the cache
    if ( hit )
    {
        // release the old data
        pthread_mutex_unlock( &cache->mutex );
        cache_object_close( cache, *hit, NULL );
        pthread_mutex_lock( &cache->mutex );
        // the MRU end gets the updated data
        hit = &alt[ cache->count - 1 ];
    }
    else if ( cache->count < CACHE_SIZE )
    {
        // more room in cache, add it to MRU end
        hit = &alt[ cache->count++ ];
    }
    else
    {
        // release the entry at the LRU end
        pthread_mutex_unlock( &cache->mutex );
        cache_object_close( cache, cache->current[0], NULL );
        pthread_mutex_lock( &cache->mutex );

        // The MRU end gets the new item
        hit = &alt[ cache->count - 1 ];
    }
    *hit = object;
    mlt_log( NULL, MLT_LOG_DEBUG, "%s: put %d = %p, %p\n", __FUNCTION__, cache->count - 1, object, data );

    // Fetch the cache item
    char key[19];
    sprintf( key, "%p", object );
    mlt_cache_item item = mlt_properties_get_data( cache->active, key, NULL );
    if ( !item )
    {
        item = calloc( 1, sizeof( mlt_cache_item_s ) );
        if ( item )
            mlt_properties_set_data( cache->active, key, item, 0, free, NULL );
    }
    if ( item )
    {
        // If updating the cache item but not all references are released
        // copy the item to the garbage collection.
        if ( item->refcount > 0 && item->data )
        {
            mlt_cache_item orphan = calloc( 1, sizeof( mlt_cache_item_s ) );
            if ( orphan )
            {
                mlt_log( NULL, MLT_LOG_DEBUG, "adding to garbage collection object %p data %p\n", item->object, item->data );
                *orphan = *item;
                sprintf( key, "%p", orphan->data );
                // We store in the garbage collection by data address, not the owner's!
                mlt_properties_set_data( cache->garbage, key, orphan, 0, free, NULL );
            }
        }

        // Set/update the cache item
        item->cache = cache;
        item->object = object;
        item->data = data;
        item->size = size;
        item->destructor = destructor;
        item->refcount = 1;
    }

    // swap the current array
    cache->current = alt;
    pthread_mutex_unlock( &cache->mutex );
}
Exemplo n.º 6
0
Arquivo: mlt_cache.c Projeto: rayl/MLT
void mlt_cache_item_close( mlt_cache_item item )
{
    if ( item )
        cache_object_close( item->cache, item->object, item->data );
}