mirror of
https://github.com/RIOT-OS/RIOT.git
synced 2024-12-29 04:50:03 +01:00
103 lines
3.1 KiB
C
103 lines
3.1 KiB
C
/*
|
|
* Copyright (C) 2014 René Kijewski <rene.kijewski@fu-berlin.de>
|
|
*
|
|
* This file is subject to the terms and conditions of the GNU Lesser
|
|
* General Public License v2.1. See the file LICENSE in the top level
|
|
* directory for more details.
|
|
*/
|
|
|
|
/**
|
|
* @ingroup pthread
|
|
* @{
|
|
* @file
|
|
* @brief Cleanup primitives for pthread threads.
|
|
* @note Do not include this header file directly, but pthread.h.
|
|
*/
|
|
|
|
#ifndef PTHREAD_CLEANUP_H
|
|
#define PTHREAD_CLEANUP_H
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
/**
|
|
* @brief Internal structure for pthread_cleanup_push()
|
|
*/
|
|
typedef struct __pthread_cleanup_datum
|
|
{
|
|
/** Cleanup handler to call next. */
|
|
struct __pthread_cleanup_datum *__next;
|
|
|
|
/** Cleanup routine to call. */
|
|
void (*__routine)(void *arg);
|
|
|
|
/** Argument to supply. */
|
|
void *__arg;
|
|
} __pthread_cleanup_datum_t;
|
|
|
|
/**
|
|
* @brief Internal function to be called by pthread_cleanup_push()
|
|
* @details The previous top of the stack gets stored in `datum->next`.
|
|
* @param[in] datum Allocated in the stack, datum tells how to cleanup.
|
|
*/
|
|
void __pthread_cleanup_push(__pthread_cleanup_datum_t *datum);
|
|
|
|
/**
|
|
* @brief Internal function to be called by pthread_cleanup_push()
|
|
* @details This function leaves the cleanup frame that was opened with __pthread_cleanup_push().
|
|
* @param[in] datum Parameter that was supplied to __pthread_cleanup_push().
|
|
* @param[in] execute Iff `!= 0` call cleanup handler.
|
|
*/
|
|
void __pthread_cleanup_pop(__pthread_cleanup_datum_t *datum, int execute);
|
|
|
|
/*
|
|
* Notice: `pthread_cleanup_*` has to be defined as a macro, because the cleanup
|
|
* stack needs extra data. The standard explicitly allows defining these
|
|
* functions as macros. The alternative would be malloc.
|
|
*/
|
|
|
|
/**
|
|
* @brief Open a cleanup frame.
|
|
* @details This function must be paired with pthread_cleanup_pop().
|
|
* @details The cleanup function is called if the current thread exists
|
|
* inside the frame by means of pthread_exit(), or if the thread
|
|
* was cancelled.
|
|
* @details You must not `return`, `continue`, or `break` out of the cleanup frame.
|
|
* @details The frame opens a scope. Variables declared inside this scope
|
|
* won't be visible outside.
|
|
* @param[in] ROUTINE Function to call on cleanup.
|
|
* @param[in] ARG Argument to supply to the cleanup handler.
|
|
*/
|
|
#define pthread_cleanup_push(ROUTINE, ARG) \
|
|
do { \
|
|
__extension__ __pthread_cleanup_datum_t ____datum__ = { \
|
|
.__routine = (ROUTINE), \
|
|
.__arg = (ARG), \
|
|
}; \
|
|
__extension__ int ____execute__ = 1; \
|
|
__pthread_cleanup_push(&____datum__); \
|
|
do { \
|
|
do { } while (0)
|
|
|
|
/**
|
|
* @brief Closes a cleaup frame
|
|
* @details Must be paired with pthread_cleanup_push().
|
|
* @param[in] EXECUTE Iff `!= 0` call cleanup handler.
|
|
*/
|
|
#define pthread_cleanup_pop(EXECUTE) \
|
|
____execute__ = (EXECUTE); \
|
|
} while (0); \
|
|
__pthread_cleanup_pop(&____datum__, ____execute__); \
|
|
} while (0)
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif /* PTHREAD_CLEANUP_H */
|
|
|
|
/**
|
|
* @}
|
|
*/
|