1 .\" Automatically generated by Pod::Man 2.1801 (Pod::Simple 3.08)
2 .\"
3 .\" Standard preamble:
4 .\" ========================================================================
5 .de Sp \" Vertical space (when we can't use .PP)
6 .if t .sp .5v
7 .if n .sp
8 ..
9 .de Vb \" Begin verbatim text
10 .ft CW
11 .nf
12 .ne \\$1
13 ..
14 .de Ve \" End verbatim text
15 .ft R
16 .fi
17 ..
18 .\" Set up some character translations and predefined strings. \*(-- will
19 .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left
20 .\" double quote, and \*(R" will give a right double quote. \*(C+ will
21 .\" give a nicer C++. Capital omega is used to do unbreakable dashes and
22 .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff,
23 .\" nothing in troff, for use with C<>.
24 .tr \(*W-
25 .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p'
26 .ie n \{\
27 . ds -- \(*W-
28 . ds PI pi
29 . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch
30 . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch
31 . ds L" ""
32 . ds R" ""
33 . ds C` ""
34 . ds C' ""
35 'br\}
36 .el\{\
37 . ds -- \|\(em\|
38 . ds PI \(*p
39 . ds L" ``
40 . ds R" ''
41 'br\}
42 .\"
43 .\" Escape single quotes in literal strings from groff's Unicode transform.
44 .ie \n(.g .ds Aq \(aq
45 .el .ds Aq '
46 .\"
47 .\" If the F register is turned on, we'll generate index entries on stderr for
48 .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index
49 .\" entries marked with X<> in POD. Of course, you'll have to process the
50 .\" output yourself in some meaningful fashion.
51 .ie \nF \{\
52 . de IX
53 . tm Index:\\$1\t\\n%\t"\\$2"
54 ..
55 . nr % 0
56 . rr F
57 .\}
58 .el \{\
59 . de IX
60 ..
61 .\}
62 .\"
63 .\" Accent mark definitions (@(#)ms.acc 1.5 88/02/08 SMI; from UCB 4.2).
64 .\" Fear. Run. Save yourself. No user-serviceable parts.
65 . \" fudge factors for nroff and troff
66 .if n \{\
67 . ds #H 0
68 . ds #V .8m
69 . ds #F .3m
70 . ds #[ \f1
71 . ds #] \fP
72 .\}
73 .if t \{\
74 . ds #H ((1u-(\\\\n(.fu%2u))*.13m)
75 . ds #V .6m
76 . ds #F 0
77 . ds #[ \&
78 . ds #] \&
79 .\}
80 . \" simple accents for nroff and troff
81 .if n \{\
82 . ds ' \&
83 . ds ` \&
84 . ds ^ \&
85 . ds , \&
86 . ds ~ ~
87 . ds /
88 .\}
89 .if t \{\
90 . ds ' \\k:\h'-(\\n(.wu*8/10-\*(#H)'\'\h"|\\n:u"
91 . ds ` \\k:\h'-(\\n(.wu*8/10-\*(#H)'\`\h'|\\n:u'
92 . ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'^\h'|\\n:u'
93 . ds , \\k:\h'-(\\n(.wu*8/10)',\h'|\\n:u'
94 . ds ~ \\k:\h'-(\\n(.wu-\*(#H-.1m)'~\h'|\\n:u'
95 . ds / \\k:\h'-(\\n(.wu*8/10-\*(#H)'\z\(sl\h'|\\n:u'
96 .\}
97 . \" troff and (daisy-wheel) nroff accents
98 .ds : \\k:\h'-(\\n(.wu*8/10-\*(#H+.1m+\*(#F)'\v'-\*(#V'\z.\h'.2m+\*(#F'.\h'|\\n:u'\v'\*(#V'
99 .ds 8 \h'\*(#H'\(*b\h'-\*(#H'
100 .ds o \\k:\h'-(\\n(.wu+\w'\(de'u-\*(#H)/2u'\v'-.3n'\*(#[\z\(de\v'.3n'\h'|\\n:u'\*(#]
101 .ds d- \h'\*(#H'\(pd\h'-\w'~'u'\v'-.25m'\f2\(hy\fP\v'.25m'\h'-\*(#H'
102 .ds D- D\\k:\h'-\w'D'u'\v'-.11m'\z\(hy\v'.11m'\h'|\\n:u'
103 .ds th \*(#[\v'.3m'\s+1I\s-1\v'-.3m'\h'-(\w'I'u*2/3)'\s-1o\s+1\*(#]
104 .ds Th \*(#[\s+2I\s-2\h'-\w'I'u*3/5'\v'-.3m'o\v'.3m'\*(#]
105 .ds ae a\h'-(\w'a'u*4/10)'e
106 .ds Ae A\h'-(\w'A'u*4/10)'E
107 . \" corrections for vroff
108 .if v .ds ~ \\k:\h'-(\\n(.wu*9/10-\*(#H)'\s-2\u~\d\s+2\h'|\\n:u'
109 .if v .ds ^ \\k:\h'-(\\n(.wu*10/11-\*(#H)'\v'-.4m'^\v'.4m'\h'|\\n:u'
110 . \" for low resolution devices (crt and lpr)
111 .if \n(.H>23 .if \n(.V>19 \
112 \{\
113 . ds : e
114 . ds 8 ss
115 . ds o a
116 . ds d- d\h'-1'\(ga
117 . ds D- D\h'-1'\(hy
118 . ds th \o'bp'
119 . ds Th \o'LP'
120 . ds ae ae
121 . ds Ae AE
122 .\}
123 .rm #[ #] #H #V #F C
124 .\" ========================================================================
125 .\"
126 .IX Title "RRDTHREADS 1"
127 .TH RRDTHREADS 1 "2009-04-19" "1.3.999" "rrdtool"
128 .\" For nroff, turn off justification. Always turn off hyphenation; it makes
129 .\" way too many mistakes in technical documents.
130 .if n .ad l
131 .nh
132 .SH "NAME"
133 rrdthreads \- Provisions for linking the RRD library to use in multi\-threaded programs
134 .SH "SYNOPSIS"
135 .IX Header "SYNOPSIS"
136 Using librrd in multi-threaded programs requires some extra
137 precautions, as the \s-1RRD\s0 library in its original form was not
138 thread-safe at all. This document describes requirements and pitfalls
139 on the way to use the multi-threaded version of librrd in your own
140 programs. It also gives hints for future \s-1RRD\s0 development to keep the
141 library thread-safe.
142 .PP
143 Currently only some \s-1RRD\s0 operations are implemented in a thread-safe
144 way. They all end in the usual "\f(CW\*(C`_r\*(C'\fR" suffix.
145 .SH "DESCRIPTION"
146 .IX Header "DESCRIPTION"
147 In order to use librrd in multi-threaded programs you must:
148 .IP "\(bu" 4
149 Link with \fIlibrrd_th\fR instead of \fIlibrrd\fR (use \f(CW\*(C`\-lrrd_th\*(C'\fR when
150 linking)
151 .IP "\(bu" 4
152 Use the "\f(CW\*(C`_r\*(C'\fR" functions instead of the normal API-functions
153 .IP "\(bu" 4
154 Do not use any at-style time specifications. Parsing of such time
155 specifications is terribly non-thread-safe.
156 .IP "\(bu" 4
157 Never use non *\f(CW\*(C`_r\*(C'\fR functions unless it is explicitly documented that
158 the function is tread-safe.
159 .IP "\(bu" 4
160 Every thread \s-1SHOULD\s0 call \f(CW\*(C`rrd_get_context()\*(C'\fR before its first call to
161 any \f(CW\*(C`librrd_th\*(C'\fR function in order to set up thread specific data. This
162 is not strictly required, but it is the only way to test if memory
163 allocation can be done by this function. Otherwise the program may die
164 with a \s-1SIGSEGV\s0 in a low-memory situation.
165 .IP "\(bu" 4
166 Always call \f(CW\*(C`rrd_error_clear()\*(C'\fR before any call to the
167 library. Otherwise the call might fail due to some earlier error.
168 .SS "\s-1NOTES\s0 \s-1FOR\s0 \s-1RRD\s0 \s-1CONTRIBUTORS\s0"
169 .IX Subsection "NOTES FOR RRD CONTRIBUTORS"
170 Some precautions must be followed when developing \s-1RRD\s0 from now on:
171 .IP "\(bu" 4
172 Only use thread-safe functions in library code. Many often used libc
173 functions aren't thread-safe. Take care in the following
174 situations or when using the following library functions:
175 .RS 4
176 .IP "\(bu" 4
177 Direct calls to \f(CW\*(C`strerror()\*(C'\fR must be avoided: use \f(CW\*(C`rrd_strerror()\*(C'\fR
178 instead, it provides a per-thread error message.
179 .IP "\(bu" 4
180 The \f(CW\*(C`getpw*\*(C'\fR, \f(CW\*(C`getgr*\*(C'\fR, \f(CW\*(C`gethost*\*(C'\fR function families (and some more
181 \&\f(CW\*(C`get*\*(C'\fR functions) are not thread-safe: use the *\f(CW\*(C`_r\*(C'\fR variants
182 .IP "\(bu" 4
183 Time functions: \f(CW\*(C`asctime\*(C'\fR, \f(CW\*(C`ctime\*(C'\fR, \f(CW\*(C`gmtime\*(C'\fR, \f(CW\*(C`localtime\*(C'\fR: use
184 *\f(CW\*(C`_r\*(C'\fR variants
185 .IP "\(bu" 4
186 \&\f(CW\*(C`strtok\*(C'\fR: use \f(CW\*(C`strtok_r\*(C'\fR
187 .IP "\(bu" 4
188 \&\f(CW\*(C`tmpnam\*(C'\fR: use \f(CW\*(C`tmpnam_r\*(C'\fR
189 .IP "\(bu" 4
190 Many others (lookup documentation)
191 .RE
192 .RS 4
193 .RE
194 .IP "\(bu" 4
195 A header file named \fIrrd_is_thread_safe.h\fR is provided
196 that works with the \s-1GNU\s0 C\-preprocessor to \*(L"poison\*(R" some of the most
197 common non-thread-safe functions using the \f(CW\*(C`#pragma GCC poison\*(C'\fR
198 directive. Just include this header in source files you want to keep
199 thread-safe.
200 .IP "\(bu" 4
201 Do not introduce global variables!
202 .Sp
203 If you really, really have to use a global variable you may add a new
204 field to the \f(CW\*(C`rrd_context\*(C'\fR structure and modify \fIrrd_error.c\fR,
205 \&\fIrrd_thread_safe.c\fR and \fIrrd_non_thread_safe.c\fR
206 .IP "\(bu" 4
207 Do not use \f(CW\*(C`getopt\*(C'\fR or \f(CW\*(C`getopt_long\*(C'\fR in *\f(CW\*(C`_r\*(C'\fR (neither directly nor
208 indirectly).
209 .Sp
210 \&\f(CW\*(C`getopt\*(C'\fR uses global variables and behaves badly in a multi-threaded
211 application when called concurrently. Instead provide a *_r function
212 taking all options as function parameters. You may provide argc and
213 **argv arguments for variable length argument lists. See
214 \&\f(CW\*(C`rrd_update_r\*(C'\fR as an example.
215 .IP "\(bu" 4
216 Do not use the \f(CW\*(C`rrd_parsetime\*(C'\fR function!
217 .Sp
218 It uses lots of global variables. You may use it in functions not designed
219 to be thread-safe, like in functions wrapping the \f(CW\*(C`_r\*(C'\fR version of some
220 operation (e.g., \f(CW\*(C`rrd_create\*(C'\fR, but not in \f(CW\*(C`rrd_create_r\*(C'\fR)
221 .SS "\s-1CURRENTLY\s0 \s-1IMPLEMENTED\s0 \s-1THREAD\s0 \s-1SAFE\s0 \s-1FUNCTIONS\s0"
222 .IX Subsection "CURRENTLY IMPLEMENTED THREAD SAFE FUNCTIONS"
223 Currently there exist thread-safe variants of \f(CW\*(C`rrd_update\*(C'\fR,
224 \&\f(CW\*(C`rrd_create\*(C'\fR, \f(CW\*(C`rrd_dump\*(C'\fR, \f(CW\*(C`rrd_info\*(C'\fR, \f(CW\*(C`rrd_last\*(C'\fR, and \f(CW\*(C`rrd_fetch\*(C'\fR.
225 .SH "AUTHOR"
226 .IX Header "AUTHOR"
227 Peter Stamfest <peter@stamfest.at>