1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
|
From b26db0813ca2aab8882535caa9d0a6c8671e9bbc Mon Sep 17 00:00:00 2001
From: "Peter S. Mazinger" <ps.m@gmx.net>
Date: Thu, 21 Apr 2011 21:19:39 +0200
Subject: [PATCH 1/6] cancel.h: add generic file to ease cancellation support
Signed-off-by: Peter S. Mazinger <ps.m@gmx.net>
Signed-off-by: Bernhard Reutner-Fischer <rep.dot.nop@gmail.com>
(cherry picked from commit 9f68f0cbf8c8eea6a7f9e195e4617bbaa808d7c6)
Conflicts:
Makefile.in
---
Makefile.in | 1 +
include/cancel.h | 101 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 102 insertions(+)
create mode 100644 include/cancel.h
diff --git a/Makefile.in b/Makefile.in
index 9ba590d..e81926d 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -210,6 +210,7 @@ $(top_builddir)extra/scripts/unifdef: $(top_srcdir)extra/scripts/unifdef.c
# a "y" here means the feature is enabled and so we should *not* rm it.
# if the option expands to nothing though, we can punt the headers.
HEADERS_RM- := \
+ cancel.h \
dl-osinfo.h \
hp-timing.h \
_lfs_64.h \
diff --git a/include/cancel.h b/include/cancel.h
new file mode 100644
index 0000000..ac6f6b6
--- /dev/null
+++ b/include/cancel.h
@@ -0,0 +1,101 @@
+/* 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
--
1.7.11.1
|