| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101 | /* vi: set sw=4 ts=4: *//* * Copyright (C) 2000-2011 Erik Andersen <andersen@uclibc.org> * * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball. */#ifndef _CANCEL_H#define _CANCEL_H/* * Usage of this header: * 1. define a static or hidden function __NC(NAME) - expands to __NAME_nocancel * 2. if it is hidden, add the prototype to the appropiate header where NAME has * it's prototype (guarded by _LIBC) * 3. add a CANCELLABLE_SYSCALL(...) line at the end, this will create the function * NAME (as weak) with enabled cancellation for NPTL (and later for new LT), for * LT_OLD it will also create a strong_alias to __libc_NAME to be used in libpthread * 4. if you need libc_hidden_(weak|def) line, use instead lt_libc_hidden, this will * take care of the correct type, weak or strong depending on the THREADS type * 5. If the implementation can't be done using CANCELLABLE_SYSCALL (like for fcntl) * you need to manually add lt_strong_alias() line too, to optionally create the * __libc_NAME alias * 6. if functions are needed to implement __NC(NAME), that themselves are cancellable, * decide how the cancellation should be solved, two variants are possible: *  a. use the other function as __NC(FUNC), this way you access the non-cancellable *  variant and provide by CANCELLABLE_SYSCALL(...) the dedicated cancellation for NAME. *  be aware, that for this case __NC(FUNC) has to be hidden (not static) *  b. use the other function with it's name (FUNC) and add LIBC_CANCEL_HANDLED(); at *  the end of file with a comment telling us which function took care of the cancellation * Note: LIBC_CANCEL_HANDLED() is noop on uClibc, glibc uses it only for tests, we use * it only for "documentation". * * For now the use of this file is limited to libc, will expand later to support libpthread * and librt as well. */#include <features.h>#ifndef NOT_IN_libc#define __NC(name) _NC(name)#define _NC(name) __##name##_nocancel#define __NC_OLD(name) _NC_OLD(name)#define _NC_OLD(name) __libc_##name#define __NC_PROTO(name) extern __typeof(name) __NC(name) attribute_hidden;#define __NC_OLD_PROTO(name) extern __typeof(name) __NC_OLD(name);#if defined __UCLIBC_HAS_THREADS__ && !defined __LINUXTHREADS_OLD__# define __NEW_THREADS 1#else# define SINGLE_THREAD_P 1#endif#ifdef __NEW_THREADS# include <sysdep-cancel.h># define CANCELLABLE_SYSCALL(res_type, name, param_list, params)	\res_type weak_function name param_list					\{									\	if (SINGLE_THREAD_P)						\		return __NC(name) params;				\	int oldtype = LIBC_CANCEL_ASYNC();				\	res_type result = __NC(name) params;				\	LIBC_CANCEL_RESET(oldtype);					\	return result;							\}# define lt_strong_alias(name)# define lt_libc_hidden(name) libc_hidden_def(name)#elif defined __LINUXTHREADS_OLD__# define CANCELLABLE_SYSCALL(res_type, name, param_list, params)	\weak_alias(__NC(name),name)						\lt_strong_alias(name)# define lt_strong_alias(name)						\__NC_OLD_PROTO(name)							\strong_alias(name,__NC_OLD(name))# define lt_libc_hidden(name) libc_hidden_weak(name)#else# define CANCELLABLE_SYSCALL(res_type, name, param_list, params)	\strong_alias(__NC(name),name)# define lt_strong_alias(name)# define lt_libc_hidden(name) libc_hidden_def(name)#endif/* disable it, useless, glibc uses it only for tests */# undef LIBC_CANCEL_HANDLED# define LIBC_CANCEL_HANDLED()#endif /* NOT_IN_libc */#endif
 |