1 /*****************************************************************************
2 * media_pool.c : Media pool for watching system
3 *****************************************************************************
4 * Copyright (C) 2009-2010 the VideoLAN team and AUTHORS
7 * Authors: Srikanth Raju <srikiraju at gmail dot com>
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22 *****************************************************************************/
24 #include "sql_media_library.h"
26 #define mp_foreachlist( a, b ) for( ml_poolobject_t* b = a; b; b = b->p_next )
28 static inline int mediapool_hash( int media_id )
30 return media_id % ML_MEDIAPOOL_HASH_LENGTH;
34 * @brief Get a media from the pool
35 * @param p_ml ML object
36 * @param media_id The media id of the object to get
37 * @return the found media or NULL if not found
39 ml_media_t* pool_GetMedia( media_library_t* p_ml, int media_id )
41 vlc_mutex_lock( &p_ml->p_sys->pool_mutex );
42 ml_media_t* p_media = NULL;
43 mp_foreachlist( p_ml->p_sys->p_mediapool[ mediapool_hash( media_id ) ], p_item )
45 if( p_item->p_media->i_id == media_id )
47 p_media = p_item->p_media;
52 ml_gc_incref( p_media );
53 vlc_mutex_unlock( &p_ml->p_sys->pool_mutex );
58 * @brief Insert a media into the media pool
59 * @param p_ml ML object
60 * @param p_media Media object to insert
61 * @return VLC_SUCCESS or VLC_EGENERIC
63 int pool_InsertMedia( media_library_t* p_ml, ml_media_t* p_media, bool locked )
66 ml_LockMedia( p_media );
68 assert( p_media->i_id > 0 );
69 vlc_spin_lock( &p_media->ml_gc_data.spin );
70 if( p_media->ml_gc_data.pool )
72 msg_Dbg( p_ml, "Already in pool! %s %d", p_media->psz_uri, p_media->i_id );
73 ml_UnlockMedia( p_media );
76 p_media->ml_gc_data.pool = true;
77 vlc_spin_unlock( &p_media->ml_gc_data.spin );
78 int i_ret = VLC_SUCCESS;
79 vlc_mutex_lock( &p_ml->p_sys->pool_mutex );
80 mp_foreachlist( p_ml->p_sys->p_mediapool[ (mediapool_hash(p_media->i_id)) ], p_item )
82 if( p_media == p_item->p_media )
87 else if( p_media->i_id == p_item->p_media->i_id )
90 msg_Warn( p_ml, "A media of the same id was found, but in different objects!" );
94 if( i_ret == VLC_SUCCESS )
96 ml_poolobject_t* p_new = ( ml_poolobject_t * ) calloc( 1, sizeof( ml_poolobject_t* ) );
101 ml_gc_incref( p_media );
102 p_new->p_media = p_media;
103 p_new->p_next = p_ml->p_sys->p_mediapool[ ( mediapool_hash( p_media->i_id ) ) ];
104 p_ml->p_sys->p_mediapool[ ( mediapool_hash( p_media->i_id ) ) ] = p_new;
107 vlc_mutex_unlock( &p_ml->p_sys->pool_mutex );
109 ml_UnlockMedia( p_media );
114 * @brief Perform a single garbage collection scan on the media pool
115 * @param p_ml The ML object
116 * @note Scans all media and removes any medias not held by any other objects.
118 void pool_GC( media_library_t* p_ml )
120 vlc_mutex_lock( &p_ml->p_sys->pool_mutex );
121 ml_poolobject_t* p_prev = NULL;
122 ml_media_t* p_media = NULL;
123 for( int i_idx = 0; i_idx < ML_MEDIAPOOL_HASH_LENGTH; i_idx++ )
126 for( ml_poolobject_t* p_item = p_ml->p_sys->p_mediapool[ i_idx ];
127 p_item != NULL; p_item = p_item->p_next )
129 p_media = p_item->p_media;
131 vlc_spin_lock( &p_media->ml_gc_data.spin );
132 refs = p_media->ml_gc_data.refs;
133 vlc_spin_unlock( &p_media->ml_gc_data.spin );
137 p_ml->p_sys->p_mediapool[i_idx] = p_item->p_next;
139 p_prev->p_next = p_item->p_next;
140 vlc_spin_lock( &p_media->ml_gc_data.spin );
141 p_media->ml_gc_data.pool = false;
142 vlc_spin_unlock( &p_media->ml_gc_data.spin );
143 ml_gc_decref( p_item->p_media );//This should destroy the object
149 vlc_mutex_unlock( &p_ml->p_sys->pool_mutex );