OSDN Git Service

cancel.h: add generic file to ease cancellation support
[uclinux-h8/uClibc.git] / include / cancel.h
1 /* vi: set sw=4 ts=4: */
2 /*
3  * Copyright (C) 2000-2011 Erik Andersen <andersen@uclibc.org>
4  *
5  * Licensed under the LGPL v2.1, see the file COPYING.LIB in this tarball.
6  */
7
8 #ifndef _CANCEL_H
9 #define _CANCEL_H
10
11 /*
12  * Usage of this header:
13  * 1. define a static or hidden function __NC(NAME) - expands to __NAME_nocancel
14  * 2. if it is hidden, add the prototype to the appropiate header where NAME has
15  * it's prototype (guarded by _LIBC)
16  * 3. add a CANCELLABLE_SYSCALL(...) line at the end, this will create the function
17  * NAME (as weak) with enabled cancellation for NPTL (and later for new LT), for
18  * LT_OLD it will also create a strong_alias to __libc_NAME to be used in libpthread
19  * 4. if you need libc_hidden_(weak|def) line, use instead lt_libc_hidden, this will
20  * take care of the correct type, weak or strong depending on the THREADS type
21  * 5. If the implementation can't be done using CANCELLABLE_SYSCALL (like for fcntl)
22  * you need to manually add lt_strong_alias() line too, to optionally create the
23  * __libc_NAME alias
24  * 6. if functions are needed to implement __NC(NAME), that themselves are cancellable,
25  * decide how the cancellation should be solved, two variants are possible:
26  *  a. use the other function as __NC(FUNC), this way you access the non-cancellable
27  *  variant and provide by CANCELLABLE_SYSCALL(...) the dedicated cancellation for NAME.
28  *  be aware, that for this case __NC(FUNC) has to be hidden (not static)
29  *  b. use the other function with it's name (FUNC) and add LIBC_CANCEL_HANDLED(); at
30  *  the end of file with a comment telling us which function took care of the cancellation
31  * Note: LIBC_CANCEL_HANDLED() is noop on uClibc, glibc uses it only for tests, we use
32  * it only for "documentation".
33  *
34  * For now the use of this file is limited to libc, will expand later to support libpthread
35  * and librt as well.
36  */
37
38 #include <features.h>
39
40 #ifndef NOT_IN_libc
41
42 #define __NC(name) _NC(name)
43 #define _NC(name) __##name##_nocancel
44
45 #define __NC_OLD(name) _NC_OLD(name)
46 #define _NC_OLD(name) __libc_##name
47
48 #define __NC_PROTO(name) extern __typeof(name) __NC(name) attribute_hidden;
49 #define __NC_OLD_PROTO(name) extern __typeof(name) __NC_OLD(name);
50
51 #if defined __UCLIBC_HAS_THREADS__ && !defined __LINUXTHREADS_OLD__
52 # define __NEW_THREADS 1
53 #else
54 # define SINGLE_THREAD_P 1
55 #endif
56
57 #ifdef __NEW_THREADS
58 # include <sysdep-cancel.h>
59
60 # define CANCELLABLE_SYSCALL(res_type, name, param_list, params)        \
61 res_type weak_function name param_list                                  \
62 {                                                                       \
63         if (SINGLE_THREAD_P)                                            \
64                 return __NC(name) params;                               \
65         int oldtype = LIBC_CANCEL_ASYNC();                              \
66         res_type result = __NC(name) params;                            \
67         LIBC_CANCEL_RESET(oldtype);                                     \
68         return result;                                                  \
69 }
70
71 # define lt_strong_alias(name)
72 # define lt_libc_hidden(name) libc_hidden_def(name)
73
74 #elif defined __LINUXTHREADS_OLD__
75
76 # define CANCELLABLE_SYSCALL(res_type, name, param_list, params)        \
77 weak_alias(__NC(name),name)                                             \
78 lt_strong_alias(name)
79
80 # define lt_strong_alias(name)                                          \
81 __NC_OLD_PROTO(name)                                                    \
82 strong_alias(name,__NC_OLD(name))
83 # define lt_libc_hidden(name) libc_hidden_weak(name)
84
85 #else
86
87 # define CANCELLABLE_SYSCALL(res_type, name, param_list, params)        \
88 strong_alias(__NC(name),name)
89
90 # define lt_strong_alias(name)
91 # define lt_libc_hidden(name) libc_hidden_def(name)
92
93 #endif
94
95 /* disable it, useless, glibc uses it only for tests */
96 # undef LIBC_CANCEL_HANDLED
97 # define LIBC_CANCEL_HANDLED()
98
99 #endif /* NOT_IN_libc */
100
101 #endif