| | 321 | |
|---|
| | 322 | #if defined (LIBVLC_USE_PTHREAD) |
|---|
| | 323 | /** |
|---|
| | 324 | * Registers a new procedure to run if the thread is cancelled (or otherwise |
|---|
| | 325 | * exits prematurely). Any call to vlc_cleanup_push() <b>must</b> paired with a |
|---|
| | 326 | * call to either vlc_cleanup_pop() or vlc_cleanup_run(). Branching into or out |
|---|
| | 327 | * of the block between these two function calls is not allowed (read: it will |
|---|
| | 328 | * likely crash the whole process). If multiple procedures are registered, |
|---|
| | 329 | * they are handled in last-in first-out order. |
|---|
| | 330 | * |
|---|
| | 331 | * @param routine procedure to call if the thread ends |
|---|
| | 332 | * @param arg argument for the procedure |
|---|
| | 333 | */ |
|---|
| | 334 | # define vlc_cleanup_push( routine, arg ) pthread_cleanup_push (routine, arg) |
|---|
| | 335 | |
|---|
| | 336 | /** |
|---|
| | 337 | * Removes a cleanup procedure that was previously registered with |
|---|
| | 338 | * vlc_cleanup_push(). |
|---|
| | 339 | */ |
|---|
| | 340 | # define vlc_cleanup_pop( ) pthread_cleanup_pop (0) |
|---|
| | 341 | |
|---|
| | 342 | /** |
|---|
| | 343 | * Removes a cleanup procedure that was previously registered with |
|---|
| | 344 | * vlc_cleanup_push(), and executes it. |
|---|
| | 345 | */ |
|---|
| | 346 | # define vlc_cleanup_run( ) pthread_cleanup_pop (1) |
|---|
| | 347 | #else |
|---|
| | 348 | typedef struct vlc_cleanup_t vlc_cleanup_t; |
|---|
| | 349 | |
|---|
| | 350 | struct vlc_cleanup_t |
|---|
| | 351 | { |
|---|
| | 352 | vlc_cleanup_t *next; |
|---|
| | 353 | void (*proc) (void *); |
|---|
| | 354 | void *data; |
|---|
| | 355 | }; |
|---|
| | 356 | |
|---|
| | 357 | /* This macros opens a code block on purpose. This is needed for multiple |
|---|
| | 358 | * calls within a single function. This also prevent Win32 developpers from |
|---|
| | 359 | * writing code that would break on POSIX (POSIX opens a block as well). */ |
|---|
| | 360 | # define vlc_cleanup_push( routine, arg ) \ |
|---|
| | 361 | do { \ |
|---|
| | 362 | vlc_cleanup_t vlc_cleanup_data = { NULL, routine, arg, }; \ |
|---|
| | 363 | vlc_control_cancel (VLC_CLEANUP_PUSH, &vlc_cleanup_data) |
|---|
| | 364 | |
|---|
| | 365 | # define vlc_cleanup_pop( ) \ |
|---|
| | 366 | vlc_control_cancel (VLC_CLEANUP_POP); \ |
|---|
| | 367 | } while (0) |
|---|
| | 368 | |
|---|
| | 369 | # define vlc_cleanup_run( ) \ |
|---|
| | 370 | vlc_control_cancel (VLC_CLEANUP_POP); \ |
|---|
| | 371 | vlc_cleanup_data.proc (vlc_cleanup_data.data); \ |
|---|
| | 372 | } while (0) |
|---|
| | 373 | |
|---|
| | 374 | #endif /* LIBVLC_USE_PTHREAD */ |
|---|