summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorchristos <christos@NetBSD.org>2019-03-05 01:35:52 +0000
committerchristos <christos@NetBSD.org>2019-03-05 01:35:52 +0000
commit03bbc0809832cfc64ebef984c1dae5d64c95bfca (patch)
tree11c70e20854dd6c80f39bb8826532c3af2e9134b
parent9dc824f400679beae5c68745c5200ca0478a7c3d (diff)
Transfer all the keys that were created in the libc stub implementation
to the pthread tsd implementation when the main thread is created. This corrects a problem where a process created keys before libpthread was loaded (either from the libc constructor or because libpthread was dlopened later). This fixes a problem with jemalloc which creates keys in the constructor.
-rw-r--r--lib/libc/include/tsd.h41
-rw-r--r--lib/libc/thread-stub/thread-stub.c13
-rw-r--r--lib/libpthread/pthread.c5
-rw-r--r--lib/libpthread/pthread_int.h4
-rw-r--r--lib/libpthread/pthread_tsd.c25
5 files changed, 74 insertions, 14 deletions
diff --git a/lib/libc/include/tsd.h b/lib/libc/include/tsd.h
new file mode 100644
index 00000000000..a2d7e02f426
--- /dev/null
+++ b/lib/libc/include/tsd.h
@@ -0,0 +1,41 @@
+/* $NetBSD: tsd.h,v 1.1 2019/03/05 01:35:52 christos Exp $ */
+
+/*-
+ * Copyright (c) 2019 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+#ifndef _TSD_H_
+#define _TSD_H_
+
+#define TSD_KEYS_MAX 64
+
+struct __libc_tsd {
+ void *tsd_val;
+ void (*tsd_dtor)(void *);
+ int tsd_inuse;
+};
+
+extern struct __libc_tsd __libc_tsd[TSD_KEYS_MAX];
+
+#endif /* _TSD_H_ */
diff --git a/lib/libc/thread-stub/thread-stub.c b/lib/libc/thread-stub/thread-stub.c
index d50bd80324c..c89fafbedee 100644
--- a/lib/libc/thread-stub/thread-stub.c
+++ b/lib/libc/thread-stub/thread-stub.c
@@ -1,4 +1,4 @@
-/* $NetBSD: thread-stub.c,v 1.28 2016/10/31 18:10:11 kamil Exp $ */
+/* $NetBSD: thread-stub.c,v 1.29 2019/03/05 01:35:52 christos Exp $ */
/*-
* Copyright (c) 2003, 2009 The NetBSD Foundation, Inc.
@@ -31,7 +31,7 @@
#include <sys/cdefs.h>
#if defined(LIBC_SCCS) && !defined(lint)
-__RCSID("$NetBSD: thread-stub.c,v 1.28 2016/10/31 18:10:11 kamil Exp $");
+__RCSID("$NetBSD: thread-stub.c,v 1.29 2019/03/05 01:35:52 christos Exp $");
#endif /* LIBC_SCCS and not lint */
/*
@@ -47,6 +47,7 @@ __RCSID("$NetBSD: thread-stub.c,v 1.28 2016/10/31 18:10:11 kamil Exp $");
#define pthread_detach __libc_pthread_detach
#include "namespace.h"
#include "reentrant.h"
+#include "tsd.h"
#include <errno.h>
#include <signal.h>
@@ -280,13 +281,7 @@ __libc_rwlock_catchall_stub(rwlock_t *l)
* implementation, since some thread-safe libraries want to use it.
*/
-#define TSD_KEYS_MAX 64
-
-static struct {
- void *tsd_val;
- void (*tsd_dtor)(void *);
- int tsd_inuse;
-} __libc_tsd[TSD_KEYS_MAX];
+struct __libc_tsd __libc_tsd[TSD_KEYS_MAX];
static int __libc_tsd_nextkey;
__weak_alias(__libc_thr_keycreate,__libc_thr_keycreate_stub)
diff --git a/lib/libpthread/pthread.c b/lib/libpthread/pthread.c
index 56c060a9c35..47add900ee6 100644
--- a/lib/libpthread/pthread.c
+++ b/lib/libpthread/pthread.c
@@ -1,4 +1,4 @@
-/* $NetBSD: pthread.c,v 1.152 2018/08/19 02:10:42 kamil Exp $ */
+/* $NetBSD: pthread.c,v 1.153 2019/03/05 01:35:52 christos Exp $ */
/*-
* Copyright (c) 2001, 2002, 2003, 2006, 2007, 2008 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
-__RCSID("$NetBSD: pthread.c,v 1.152 2018/08/19 02:10:42 kamil Exp $");
+__RCSID("$NetBSD: pthread.c,v 1.153 2019/03/05 01:35:52 christos Exp $");
#define __EXPOSE_STACK 1
@@ -1330,6 +1330,7 @@ pthread__initmainstack(void)
break;
}
}
+ pthread__copy_tsd(pthread__main);
}
/*
diff --git a/lib/libpthread/pthread_int.h b/lib/libpthread/pthread_int.h
index 4a5e958393d..c364e7f638d 100644
--- a/lib/libpthread/pthread_int.h
+++ b/lib/libpthread/pthread_int.h
@@ -1,4 +1,4 @@
-/* $NetBSD: pthread_int.h,v 1.94 2017/07/02 16:41:32 joerg Exp $ */
+/* $NetBSD: pthread_int.h,v 1.95 2019/03/05 01:35:52 christos Exp $ */
/*-
* Copyright (c) 2001, 2002, 2003, 2006, 2007, 2008 The NetBSD Foundation, Inc.
@@ -290,6 +290,8 @@ pthread__self(void)
void *pthread_tsd_init(size_t *) PTHREAD_HIDE;
void pthread__destroy_tsd(pthread_t) PTHREAD_HIDE;
+void pthread__copy_tsd(pthread_t) PTHREAD_HIDE;
+
__dead void pthread__assertfunc(const char *, int, const char *, const char *)
PTHREAD_HIDE;
void pthread__errorfunc(const char *, int, const char *, const char *)
diff --git a/lib/libpthread/pthread_tsd.c b/lib/libpthread/pthread_tsd.c
index b395957aeed..666cbab85f1 100644
--- a/lib/libpthread/pthread_tsd.c
+++ b/lib/libpthread/pthread_tsd.c
@@ -1,4 +1,4 @@
-/* $NetBSD: pthread_tsd.c,v 1.16 2017/07/09 20:21:08 christos Exp $ */
+/* $NetBSD: pthread_tsd.c,v 1.17 2019/03/05 01:35:52 christos Exp $ */
/*-
* Copyright (c) 2001, 2007 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
-__RCSID("$NetBSD: pthread_tsd.c,v 1.16 2017/07/09 20:21:08 christos Exp $");
+__RCSID("$NetBSD: pthread_tsd.c,v 1.17 2019/03/05 01:35:52 christos Exp $");
/* Functions and structures dealing with thread-specific data */
#include <errno.h>
@@ -39,6 +39,7 @@ __RCSID("$NetBSD: pthread_tsd.c,v 1.16 2017/07/09 20:21:08 christos Exp $");
#include "pthread.h"
#include "pthread_int.h"
#include "reentrant.h"
+#include "tsd.h"
int pthread_keys_max;
static pthread_mutex_t tsd_mutex = PTHREAD_MUTEX_INITIALIZER;
@@ -362,3 +363,23 @@ pthread__destroy_tsd(pthread_t self)
self->pt_havespecific = 0;
pthread_mutex_lock(&self->pt_lock);
}
+
+void
+pthread__copy_tsd(pthread_t self)
+{
+ for (size_t key = 0; key < TSD_KEYS_MAX; key++) {
+
+ if (__libc_tsd[key].tsd_inuse == 0)
+ continue;
+
+ pthread__assert(pthread__tsd_destructors[key] == NULL);
+ pthread__tsd_destructors[key] = __libc_tsd[key].tsd_dtor ?
+ __libc_tsd[key].tsd_dtor : null_destructor;
+ nextkey = (key + 1) % pthread_keys_max;
+
+ self->pt_havespecific = 1;
+ struct pt_specific *pt = &self->pt_specific[key];
+ pt->pts_value = __libc_tsd[key].tsd_val;
+ __libc_tsd[key].tsd_inuse = 0;
+ }
+}