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