Fix memory leak in error path of do_ftell_wide (BZ #17370)
[glibc.git] / nptl / createthread.c
blobe718e35a11ca6d10cb05e0214c72425c4ccc5d49
1 /* Copyright (C) 2002-2014 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
3 Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, see
17 <http://www.gnu.org/licenses/>. */
19 #include <sched.h>
20 #include <setjmp.h>
21 #include <signal.h>
22 #include <stdlib.h>
23 #include <atomic.h>
24 #include <ldsodefs.h>
25 #include <tls.h>
26 #include <stdint.h>
28 #include <arch-fork.h>
31 #define CLONE_SIGNAL (CLONE_SIGHAND | CLONE_THREAD)
33 /* The <tls.h> header should define the macro TLS_DEFINE_INIT_TP such that:
34 TLS_DEFINE_INIT_TP (VAR, PD);
35 Declares and initializes a variable VAR with the value that should
36 be passed to the OS thread creation function (e.g. clone) to initialize
37 its TLS state for the 'struct pthread *' PD. */
38 #ifndef TLS_DEFINE_INIT_TP
39 /* For a transitional period while all the <tls.h> implementations are
40 getting updated, we define it using the old TLS_VALUE macro. */
41 # define TLS_DEFINE_INIT_TP(tp, pd) void *tp = TLS_VALUE
42 # ifndef TLS_VALUE
43 # define TLS_VALUE pd
44 # endif
45 #endif
47 #ifndef ARCH_CLONE
48 # define ARCH_CLONE __clone
49 #endif
52 #ifndef TLS_MULTIPLE_THREADS_IN_TCB
53 /* Pointer to the corresponding variable in libc. */
54 int *__libc_multiple_threads_ptr attribute_hidden;
55 #endif
58 static int
59 do_clone (struct pthread *pd, const struct pthread_attr *attr,
60 int clone_flags, int (*fct) (void *), STACK_VARIABLES_PARMS,
61 int stopped)
63 TLS_DEFINE_INIT_TP (tp, pd);
65 if (__glibc_unlikely (stopped != 0))
66 /* We make sure the thread does not run far by forcing it to get a
67 lock. We lock it here too so that the new thread cannot continue
68 until we tell it to. */
69 lll_lock (pd->lock, LLL_PRIVATE);
71 /* One more thread. We cannot have the thread do this itself, since it
72 might exist but not have been scheduled yet by the time we've returned
73 and need to check the value to behave correctly. We must do it before
74 creating the thread, in case it does get scheduled first and then
75 might mistakenly think it was the only thread. In the failure case,
76 we momentarily store a false value; this doesn't matter because there
77 is no kosher thing a signal handler interrupting us right here can do
78 that cares whether the thread count is correct. */
79 atomic_increment (&__nptl_nthreads);
81 int rc = ARCH_CLONE (fct, STACK_VARIABLES_ARGS, clone_flags,
82 pd, &pd->tid, tp, &pd->tid);
84 if (__glibc_unlikely (rc == -1))
86 atomic_decrement (&__nptl_nthreads); /* Oops, we lied for a second. */
88 /* Perhaps a thread wants to change the IDs and if waiting
89 for this stillborn thread. */
90 if (__builtin_expect (atomic_exchange_acq (&pd->setxid_futex, 0)
91 == -2, 0))
92 lll_futex_wake (&pd->setxid_futex, 1, LLL_PRIVATE);
94 /* Free the resources. */
95 __deallocate_stack (pd);
97 /* We have to translate error codes. */
98 return errno == ENOMEM ? EAGAIN : errno;
101 /* Now we have the possibility to set scheduling parameters etc. */
102 if (__glibc_unlikely (stopped != 0))
104 INTERNAL_SYSCALL_DECL (err);
105 int res = 0;
107 /* Set the affinity mask if necessary. */
108 if (attr->cpuset != NULL)
110 res = INTERNAL_SYSCALL (sched_setaffinity, err, 3, pd->tid,
111 attr->cpusetsize, attr->cpuset);
113 if (__glibc_unlikely (INTERNAL_SYSCALL_ERROR_P (res, err)))
115 /* The operation failed. We have to kill the thread. First
116 send it the cancellation signal. */
117 INTERNAL_SYSCALL_DECL (err2);
118 err_out:
119 (void) INTERNAL_SYSCALL (tgkill, err2, 3,
120 THREAD_GETMEM (THREAD_SELF, pid),
121 pd->tid, SIGCANCEL);
123 /* We do not free the stack here because the canceled thread
124 itself will do this. */
126 return (INTERNAL_SYSCALL_ERROR_P (res, err)
127 ? INTERNAL_SYSCALL_ERRNO (res, err)
128 : 0);
132 /* Set the scheduling parameters. */
133 if ((attr->flags & ATTR_FLAG_NOTINHERITSCHED) != 0)
135 res = INTERNAL_SYSCALL (sched_setscheduler, err, 3, pd->tid,
136 pd->schedpolicy, &pd->schedparam);
138 if (__glibc_unlikely (INTERNAL_SYSCALL_ERROR_P (res, err)))
139 goto err_out;
143 /* We now have for sure more than one thread. The main thread might
144 not yet have the flag set. No need to set the global variable
145 again if this is what we use. */
146 THREAD_SETMEM (THREAD_SELF, header.multiple_threads, 1);
148 return 0;
152 static int
153 create_thread (struct pthread *pd, const struct pthread_attr *attr,
154 STACK_VARIABLES_PARMS)
156 #if TLS_TCB_AT_TP
157 assert (pd->header.tcb != NULL);
158 #endif
160 /* We rely heavily on various flags the CLONE function understands:
162 CLONE_VM, CLONE_FS, CLONE_FILES
163 These flags select semantics with shared address space and
164 file descriptors according to what POSIX requires.
166 CLONE_SIGNAL
167 This flag selects the POSIX signal semantics.
169 CLONE_SETTLS
170 The sixth parameter to CLONE determines the TLS area for the
171 new thread.
173 CLONE_PARENT_SETTID
174 The kernels writes the thread ID of the newly created thread
175 into the location pointed to by the fifth parameters to CLONE.
177 Note that it would be semantically equivalent to use
178 CLONE_CHILD_SETTID but it is be more expensive in the kernel.
180 CLONE_CHILD_CLEARTID
181 The kernels clears the thread ID of a thread that has called
182 sys_exit() in the location pointed to by the seventh parameter
183 to CLONE.
185 The termination signal is chosen to be zero which means no signal
186 is sent. */
187 int clone_flags = (CLONE_VM | CLONE_FS | CLONE_FILES | CLONE_SIGNAL
188 | CLONE_SETTLS | CLONE_PARENT_SETTID
189 | CLONE_CHILD_CLEARTID | CLONE_SYSVSEM
190 | 0);
192 if (__glibc_unlikely (THREAD_GETMEM (THREAD_SELF, report_events)))
194 /* The parent thread is supposed to report events. Check whether
195 the TD_CREATE event is needed, too. */
196 const int _idx = __td_eventword (TD_CREATE);
197 const uint32_t _mask = __td_eventmask (TD_CREATE);
199 if ((_mask & (__nptl_threads_events.event_bits[_idx]
200 | pd->eventbuf.eventmask.event_bits[_idx])) != 0)
202 /* We always must have the thread start stopped. */
203 pd->stopped_start = true;
205 /* Create the thread. We always create the thread stopped
206 so that it does not get far before we tell the debugger. */
207 int res = do_clone (pd, attr, clone_flags, start_thread,
208 STACK_VARIABLES_ARGS, 1);
209 if (res == 0)
211 /* Now fill in the information about the new thread in
212 the newly created thread's data structure. We cannot let
213 the new thread do this since we don't know whether it was
214 already scheduled when we send the event. */
215 pd->eventbuf.eventnum = TD_CREATE;
216 pd->eventbuf.eventdata = pd;
218 /* Enqueue the descriptor. */
220 pd->nextevent = __nptl_last_event;
221 while (atomic_compare_and_exchange_bool_acq (&__nptl_last_event,
222 pd, pd->nextevent)
223 != 0);
225 /* Now call the function which signals the event. */
226 __nptl_create_event ();
228 /* And finally restart the new thread. */
229 lll_unlock (pd->lock, LLL_PRIVATE);
232 return res;
236 #ifdef NEED_DL_SYSINFO
237 assert (THREAD_SELF_SYSINFO == THREAD_SYSINFO (pd));
238 #endif
240 /* Determine whether the newly created threads has to be started
241 stopped since we have to set the scheduling parameters or set the
242 affinity. */
243 bool stopped = false;
244 if (attr != NULL && (attr->cpuset != NULL
245 || (attr->flags & ATTR_FLAG_NOTINHERITSCHED) != 0))
246 stopped = true;
247 pd->stopped_start = stopped;
248 pd->parent_cancelhandling = THREAD_GETMEM (THREAD_SELF, cancelhandling);
250 /* Actually create the thread. */
251 int res = do_clone (pd, attr, clone_flags, start_thread,
252 STACK_VARIABLES_ARGS, stopped);
254 if (res == 0 && stopped)
255 /* And finally restart the new thread. */
256 lll_unlock (pd->lock, LLL_PRIVATE);
258 return res;