Changeset a901e3b6074c1894f8e27039b5ad414df63bde75
- Timestamp:
- 08/07/07 17:22:53
(1 year ago)
- Author:
- Pierre d'Herbemont <pdherbemont@videolan.org>
- git-committer:
- Pierre d'Herbemont <pdherbemont@videolan.org> 1183908173 +0000
- git-parent:
[2f6a9d1a2bad2eee1b8ea6330af1b7dc487008da]
- git-author:
- Pierre d'Herbemont <pdherbemont@videolan.org> 1183908173 +0000
- Message:
Libvlc: Make medi_instance thread safe and implement the basics for refcounting.
-
Files:
-
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
| r40fbcb7 |
ra901e3b |
|
| 87 | 87 | struct libvlc_media_instance_t |
|---|
| 88 | 88 | { |
|---|
| | 89 | int i_refcount; |
|---|
| | 90 | vlc_mutex_t object_lock; |
|---|
| 89 | 91 | int i_input_id; /* Input object id. We don't use a pointer to |
|---|
| 90 | 92 | avoid any crash */ |
|---|
| r23942f1 |
ra901e3b |
|
| 30 | 30 | /* |
|---|
| 31 | 31 | * Release the associated input thread |
|---|
| | 32 | * |
|---|
| | 33 | * Object lock is NOT held. |
|---|
| 32 | 34 | */ |
|---|
| 33 | 35 | static void release_input_thread( libvlc_media_instance_t *p_mi ) |
|---|
| … | … | |
| 37 | 39 | libvlc_exception_t p_e; |
|---|
| 38 | 40 | |
|---|
| 39 | | /* XXX: locking */ |
|---|
| 40 | 41 | libvlc_exception_init( &p_e ); |
|---|
| 41 | 42 | |
|---|
| … | … | |
| 63 | 64 | * Retrieve the input thread. Be sure to release the object |
|---|
| 64 | 65 | * once you are done with it. (libvlc Internal) |
|---|
| | 66 | * |
|---|
| | 67 | * Object lock is held. |
|---|
| 65 | 68 | */ |
|---|
| 66 | 69 | input_thread_t *libvlc_get_input_thread( libvlc_media_instance_t *p_mi, |
|---|
| … | … | |
| 69 | 72 | input_thread_t *p_input_thread; |
|---|
| 70 | 73 | |
|---|
| | 74 | vlc_mutex_lock( &p_mi->object_lock ); |
|---|
| | 75 | |
|---|
| 71 | 76 | if( !p_mi || p_mi->i_input_id == -1 ) |
|---|
| | 77 | { |
|---|
| | 78 | vlc_mutex_unlock( &p_mi->object_lock ); |
|---|
| 72 | 79 | RAISENULL( "Input is NULL" ); |
|---|
| | 80 | } |
|---|
| 73 | 81 | |
|---|
| 74 | 82 | p_input_thread = (input_thread_t*)vlc_object_get( |
|---|
| … | … | |
| 76 | 84 | p_mi->i_input_id ); |
|---|
| 77 | 85 | if( !p_input_thread ) |
|---|
| | 86 | { |
|---|
| | 87 | vlc_mutex_unlock( &p_mi->object_lock ); |
|---|
| 78 | 88 | RAISENULL( "Input does not exist" ); |
|---|
| 79 | | |
|---|
| | 89 | } |
|---|
| | 90 | |
|---|
| | 91 | vlc_mutex_unlock( &p_mi->object_lock ); |
|---|
| 80 | 92 | return p_input_thread; |
|---|
| 81 | 93 | } |
|---|
| … | … | |
| 101 | 113 | p_mi->p_libvlc_instance = p_libvlc_instance; |
|---|
| 102 | 114 | p_mi->i_input_id = -1; |
|---|
| | 115 | /* refcount strategy: |
|---|
| | 116 | * - All items created by _new start with a refcount set to 1 |
|---|
| | 117 | * - Accessor _release decrease the refcount by 1, if after that |
|---|
| | 118 | * operation the refcount is 0, the object is destroyed. |
|---|
| | 119 | * - Accessor _retain increase the refcount by 1 (XXX: to implement) */ |
|---|
| | 120 | p_mi->i_refcount = 1; |
|---|
| | 121 | /* object_lock strategy: |
|---|
| | 122 | * - No lock held in constructor |
|---|
| | 123 | * - Lock when accessing all variable this lock is held |
|---|
| | 124 | * - Lock when attempting to destroy the object the lock is also held */ |
|---|
| | 125 | vlc_mutex_init( p_mi->p_libvlc_instance->p_libvlc_int, |
|---|
| | 126 | &p_mi->object_lock ); |
|---|
| 103 | 127 | |
|---|
| 104 | 128 | return p_mi; |
|---|
| … | … | |
| 125 | 149 | p_mi->p_libvlc_instance = p_mi->p_md->p_libvlc_instance; |
|---|
| 126 | 150 | p_mi->i_input_id = -1; |
|---|
| | 151 | /* same strategy as before */ |
|---|
| | 152 | p_mi->i_refcount = 1; |
|---|
| | 153 | /* same strategy as before */ |
|---|
| | 154 | vlc_mutex_init( p_mi->p_libvlc_instance->p_libvlc_int, |
|---|
| | 155 | &p_mi->object_lock ); |
|---|
| 127 | 156 | |
|---|
| 128 | 157 | return p_mi; |
|---|
| … | … | |
| 167 | 196 | /************************************************************************** |
|---|
| 168 | 197 | * Destroy a Media Instance object (libvlc internal) |
|---|
| | 198 | * |
|---|
| | 199 | * Warning: No lock held here, but hey, this is internal. |
|---|
| 169 | 200 | **************************************************************************/ |
|---|
| 170 | 201 | void libvlc_media_instance_destroy( libvlc_media_instance_t *p_mi ) |
|---|
| … | … | |
| 173 | 204 | libvlc_exception_t p_e; |
|---|
| 174 | 205 | |
|---|
| 175 | | /* XXX: locking */ |
|---|
| 176 | 206 | libvlc_exception_init( &p_e ); |
|---|
| 177 | 207 | |
|---|
| … | … | |
| 196 | 226 | void libvlc_media_instance_release( libvlc_media_instance_t *p_mi ) |
|---|
| 197 | 227 | { |
|---|
| 198 | | /* XXX: locking */ |
|---|
| 199 | | |
|---|
| 200 | 228 | if( !p_mi ) |
|---|
| 201 | 229 | return; |
|---|
| 202 | 230 | |
|---|
| | 231 | vlc_mutex_lock( &p_mi->object_lock ); |
|---|
| | 232 | |
|---|
| | 233 | p_mi->i_refcount--; |
|---|
| | 234 | if( p_mi->i_refcount > 0 ) |
|---|
| | 235 | { |
|---|
| | 236 | vlc_mutex_unlock( &p_mi->object_lock ); |
|---|
| | 237 | return; |
|---|
| | 238 | } |
|---|
| | 239 | |
|---|
| 203 | 240 | release_input_thread( p_mi ); |
|---|
| 204 | 241 | |
|---|
| 205 | 242 | libvlc_media_descriptor_destroy( p_mi->p_md ); |
|---|
| 206 | 243 | |
|---|
| | 244 | vlc_mutex_unlock( &p_mi->object_lock ); |
|---|
| 207 | 245 | free( p_mi ); |
|---|
| 208 | 246 | } |
|---|
| … | … | |
| 218 | 256 | (void)p_e; |
|---|
| 219 | 257 | |
|---|
| 220 | | /* XXX : lock */ |
|---|
| 221 | | |
|---|
| 222 | 258 | if( !p_mi ) |
|---|
| 223 | 259 | return; |
|---|
| 224 | 260 | |
|---|
| | 261 | vlc_mutex_lock( &p_mi->object_lock ); |
|---|
| | 262 | |
|---|
| 225 | 263 | release_input_thread( p_mi ); |
|---|
| 226 | 264 | |
|---|
| … | … | |
| 230 | 268 | { |
|---|
| 231 | 269 | p_mi->p_md = NULL; |
|---|
| | 270 | vlc_mutex_unlock( &p_mi->object_lock ); |
|---|
| 232 | 271 | return; /* It is ok to pass a NULL md */ |
|---|
| 233 | 272 | } |
|---|
| … | … | |
| 239 | 278 | p_mi->p_libvlc_instance = p_md->p_libvlc_instance; |
|---|
| 240 | 279 | |
|---|
| | 280 | vlc_mutex_unlock( &p_mi->object_lock ); |
|---|
| 241 | 281 | } |
|---|
| 242 | 282 | |
|---|
| … | … | |
| 265 | 305 | input_thread_t * p_input_thread; |
|---|
| 266 | 306 | |
|---|
| 267 | | if( p_mi->i_input_id != -1) |
|---|
| 268 | | { |
|---|
| | 307 | vlc_mutex_lock( &p_mi->object_lock ); |
|---|
| | 308 | |
|---|
| | 309 | if( p_input_thread = libvlc_get_input_thread( p_mi, p_e ) ) |
|---|
| | 310 | { |
|---|
| | 311 | /* A thread alread exists, send it a play message */ |
|---|
| 269 | 312 | vlc_value_t val; |
|---|
| 270 | 313 | val.i_int = PLAYING_S; |
|---|
| 271 | 314 | |
|---|
| 272 | | /* A thread alread exists, send it a play message */ |
|---|
| 273 | | p_input_thread = libvlc_get_input_thread( p_mi, p_e ); |
|---|
| 274 | | |
|---|
| 275 | | if( !p_input_thread ) |
|---|
| 276 | | return; |
|---|
| 277 | | |
|---|
| 278 | 315 | input_Control( p_input_thread, INPUT_CONTROL_SET_STATE, PLAYING_S ); |
|---|
| 279 | 316 | vlc_object_release( p_input_thread ); |
|---|
| … | … | |
| 281 | 318 | } |
|---|
| 282 | 319 | |
|---|
| | 320 | vlc_mutex_lock( &p_mi->object_lock ); |
|---|
| | 321 | |
|---|
| 283 | 322 | if( !p_mi->p_md ) |
|---|
| 284 | 323 | { |
|---|
| 285 | 324 | libvlc_exception_raise( p_e, "no associated media descriptor" ); |
|---|
| | 325 | vlc_mutex_unlock( &p_mi->object_lock ); |
|---|
| 286 | 326 | return; |
|---|
| 287 | 327 | } |
|---|
| … | … | |
| 293 | 333 | /* will be released in media_instance_release() */ |
|---|
| 294 | 334 | vlc_object_yield( p_input_thread ); |
|---|
| | 335 | |
|---|
| | 336 | vlc_mutex_unlock( &p_mi->object_lock ); |
|---|
| 295 | 337 | } |
|---|
| 296 | 338 | |
|---|