Changeset 259aca484038fd448c192134f8aa539f250ddf2e
- Timestamp:
- 28/08/07 03:43:11
(1 year ago)
- Author:
- Pierre d'Herbemont <pdherbemont@videolan.org>
- git-committer:
- Pierre d'Herbemont <pdherbemont@videolan.org> 1188265391 +0000
- git-parent:
[2eb5e4cd2b063a299d2db9f90ff6937b26685f8c]
- git-author:
- Pierre d'Herbemont <pdherbemont@videolan.org> 1188265391 +0000
- Message:
control/event.c: Make detach-ing from an event safe: A detached callback can't be called after event_detached. Add an internal event_detach_lock_state, to bypass this feature.
-
Files:
-
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
| r2eb5e4c |
r259aca4 |
|
| 78 | 78 | ARRAY_INIT( p_em->listeners_groups ); |
|---|
| 79 | 79 | vlc_mutex_init( p_libvlc_inst->p_libvlc_int, &p_em->object_lock ); |
|---|
| 80 | | |
|---|
| | 80 | vlc_mutex_init( p_libvlc_inst->p_libvlc_int, &p_em->event_sending_lock ); |
|---|
| 81 | 81 | return p_em; |
|---|
| 82 | 82 | } |
|---|
| … | … | |
| 92 | 92 | libvlc_event_listener_t * listener; |
|---|
| 93 | 93 | |
|---|
| | 94 | vlc_mutex_destroy( &p_em->event_sending_lock ); |
|---|
| 94 | 95 | vlc_mutex_destroy( &p_em->object_lock ); |
|---|
| 95 | 96 | |
|---|
| … | … | |
| 148 | 149 | p_event->p_obj = p_em->p_obj; |
|---|
| 149 | 150 | |
|---|
| | 151 | /* Here a read/write lock would be nice */ |
|---|
| | 152 | |
|---|
| 150 | 153 | vlc_mutex_lock( &p_em->object_lock ); |
|---|
| 151 | 154 | FOREACH_ARRAY( listeners_group, p_em->listeners_groups ) |
|---|
| … | … | |
| 172 | 175 | } |
|---|
| 173 | 176 | FOREACH_END() |
|---|
| | 177 | |
|---|
| 174 | 178 | vlc_mutex_unlock( &p_em->object_lock ); |
|---|
| 175 | 179 | |
|---|
| | 180 | /* Here a read/write lock would be *especially* nice, |
|---|
| | 181 | * We would be able to send event without blocking */ |
|---|
| | 182 | /* The only reason for this lock is to be able to wait the |
|---|
| | 183 | * End of events sending with libvlc_event_manager_lock_event_sending. |
|---|
| | 184 | * This can be useful to make sure a callback is completely detached. */ |
|---|
| | 185 | vlc_mutex_lock( &p_em->event_sending_lock ); |
|---|
| 176 | 186 | listener_cached = array_listeners_cached; |
|---|
| 177 | 187 | for( i = 0; i < i_cached_listeners; i++ ) |
|---|
| … | … | |
| 180 | 190 | listener_cached++; |
|---|
| 181 | 191 | } |
|---|
| | 192 | vlc_mutex_unlock( &p_em->event_sending_lock ); |
|---|
| | 193 | |
|---|
| 182 | 194 | free( array_listeners_cached ); |
|---|
| 183 | 195 | } |
|---|
| … | … | |
| 239 | 251 | libvlc_exception_t *p_e ) |
|---|
| 240 | 252 | { |
|---|
| | 253 | libvlc_event_detach_lock_state( p_event_manager, event_type, pf_callback, |
|---|
| | 254 | p_user_data, libvlc_UnLocked, p_e ); |
|---|
| | 255 | } |
|---|
| | 256 | |
|---|
| | 257 | /************************************************************************** |
|---|
| | 258 | * libvlc_event_detach_no_lock (internal) : |
|---|
| | 259 | * |
|---|
| | 260 | * Remove a callback for an event. |
|---|
| | 261 | **************************************************************************/ |
|---|
| | 262 | void libvlc_event_detach_lock_state( libvlc_event_manager_t *p_event_manager, |
|---|
| | 263 | libvlc_event_type_t event_type, |
|---|
| | 264 | libvlc_callback_t pf_callback, |
|---|
| | 265 | void *p_user_data, |
|---|
| | 266 | libvlc_lock_state_t lockstate, |
|---|
| | 267 | libvlc_exception_t *p_e ) |
|---|
| | 268 | { |
|---|
| 241 | 269 | libvlc_event_listeners_group_t * listeners_group; |
|---|
| 242 | 270 | libvlc_event_listener_t * listener; |
|---|
| 243 | 271 | |
|---|
| | 272 | if( lockstate == libvlc_UnLocked ) |
|---|
| | 273 | vlc_mutex_lock( &p_event_manager->event_sending_lock ); |
|---|
| 244 | 274 | vlc_mutex_lock( &p_event_manager->object_lock ); |
|---|
| 245 | 275 | FOREACH_ARRAY( listeners_group, p_event_manager->listeners_groups ) |
|---|
| … | … | |
| 257 | 287 | I hate macro) */ ); |
|---|
| 258 | 288 | vlc_mutex_unlock( &p_event_manager->object_lock ); |
|---|
| | 289 | if( lockstate == libvlc_UnLocked ) |
|---|
| | 290 | vlc_mutex_unlock( &p_event_manager->event_sending_lock ); |
|---|
| 259 | 291 | return; |
|---|
| 260 | 292 | } |
|---|
| … | … | |
| 263 | 295 | FOREACH_END() |
|---|
| 264 | 296 | vlc_mutex_unlock( &p_event_manager->object_lock ); |
|---|
| | 297 | if( lockstate == libvlc_UnLocked ) |
|---|
| | 298 | vlc_mutex_unlock( &p_event_manager->event_sending_lock ); |
|---|
| 265 | 299 | |
|---|
| 266 | 300 | libvlc_exception_raise( p_e, |
|---|
| r257fdd4 |
r259aca4 |
|
| 53 | 53 | * Opaque structures for libvlc API |
|---|
| 54 | 54 | ***************************************************************************/ |
|---|
| | 55 | |
|---|
| | 56 | typedef enum libvlc_lock_state_t |
|---|
| | 57 | { |
|---|
| | 58 | libvlc_Locked, |
|---|
| | 59 | libvlc_UnLocked |
|---|
| | 60 | } libvlc_lock_state_t; |
|---|
| 55 | 61 | |
|---|
| 56 | 62 | struct libvlc_instance_t |
|---|
| … | … | |
| 225 | 231 | DECL_ARRAY(libvlc_event_listeners_group_t *) listeners_groups; |
|---|
| 226 | 232 | vlc_mutex_t object_lock; |
|---|
| | 233 | vlc_mutex_t event_sending_lock; |
|---|
| 227 | 234 | } libvlc_event_sender_t; |
|---|
| 228 | 235 | |
|---|
| … | … | |
| 261 | 268 | |
|---|
| 262 | 269 | VLC_EXPORT (void, libvlc_event_manager_register_event_type, ( libvlc_event_manager_t * p_em, libvlc_event_type_t event_type, libvlc_exception_t * p_e ) ); |
|---|
| | 270 | VLC_EXPORT (void, libvlc_event_detach_lock_state, ( libvlc_event_manager_t *p_event_manager, libvlc_event_type_t event_type, libvlc_callback_t pf_callback, |
|---|
| | 271 | void *p_user_data, libvlc_lock_state_t lockstate, libvlc_exception_t *p_e ) ); |
|---|
| 263 | 272 | |
|---|
| 264 | 273 | VLC_EXPORT (void, libvlc_event_send, ( libvlc_event_manager_t * p_em, libvlc_event_t * p_event ) ); |
|---|