Changeset aa6b5c552d671fc1fce4ca38e5aff41ae259c28e

Show
Ignore:
Timestamp:
27/08/08 21:43:09 (3 months ago)
Author:
Rémi Denis-Courmont <rdenis@simphalempin.com>
git-committer:
Rémi Denis-Courmont <rdenis@simphalempin.com> 1219866189 +0300
git-parent:

[8458705f21592934c5d2a1ebff7d8a8d7c8e63c1]

git-author:
Rémi Denis-Courmont <rdenis@simphalempin.com> 1218391571 +0300
Message:

Support for cancellation cleanup functions

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • include/vlc_threads.h

    r5e7e11d raa6b5c5  
    188188    VLC_TEST_CANCEL, 
    189189    VLC_DO_CANCEL, 
     190    VLC_CLEANUP_PUSH, 
     191    VLC_CLEANUP_POP, 
    190192}; 
    191193#endif 
     
    317319#endif 
    318320} 
     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 
     348typedef struct vlc_cleanup_t vlc_cleanup_t; 
     349 
     350struct 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 */ 
    319375 
    320376/***************************************************************************** 
  • src/misc/threads.c

    r8458705 raa6b5c5  
    865865} 
    866866 
    867 typedef struct vlc_cleanup_t 
    868 
    869     struct vlc_cleanup_t *next; 
    870     void                (*proc) (void *); 
    871     void                 *data; 
    872 } vlc_cleanup_t; 
    873  
     867#ifndef LIBVLC_USE_PTHREAD 
    874868typedef struct vlc_cancel_t 
    875869{ 
     
    878872    bool           killed; 
    879873} vlc_cancel_t; 
     874#endif 
    880875 
    881876void vlc_control_cancel (int cmd, ...) 
    882877{ 
     878    /* NOTE: This function only modifies thread-specific data, so there is no 
     879     * need to lock anything. */ 
    883880#ifdef LIBVLC_USE_PTHREAD 
    884881    (void) cmd; 
     
    936933            nfo->killed = true; 
    937934            break; 
     935 
     936        case VLC_CLEANUP_PUSH: 
     937        { 
     938            /* cleaner is a pointer to the caller stack, no need to allocate 
     939             * and copy anything. As a nice side effect, this cannot fail. */ 
     940            vlc_cleanup_t *cleaner = va_arg (ap, vlc_cleanup_t *); 
     941            cleaner->next = nfo->cleaners; 
     942            nfo->cleaners = cleaner; 
     943            break; 
     944        } 
     945 
     946        case VLC_CLEANUP_POP: 
     947        { 
     948            nfo->cleaners = nfo->cleaners->next; 
     949            break; 
     950        } 
    938951    } 
    939952    va_end (ap);