mirror of
https://sourceware.org/git/glibc.git
synced 2024-11-10 07:10:06 +00:00
Update.
2002-12-30 Ulrich Drepper <drepper@redhat.com> * malloc/thread-m.h (thread_atfork): Define using __register_atfork.
This commit is contained in:
parent
89d6e44459
commit
416d2de60b
@ -1,3 +1,7 @@
|
|||||||
|
2002-12-30 Ulrich Drepper <drepper@redhat.com>
|
||||||
|
|
||||||
|
* malloc/thread-m.h (thread_atfork): Define using __register_atfork.
|
||||||
|
|
||||||
2002-12-30 Roland McGrath <roland@redhat.com>
|
2002-12-30 Roland McGrath <roland@redhat.com>
|
||||||
|
|
||||||
* Rules (generated): Target removed.
|
* Rules (generated): Target removed.
|
||||||
|
@ -1,3 +1,44 @@
|
|||||||
|
2002-12-31 Jakub Jelinek <jakub@redhat.com>
|
||||||
|
|
||||||
|
* sysdeps/pthread/list.h: New file.
|
||||||
|
* sysdeps/unix/sysv/linux/jmp-unwind.c: New file.
|
||||||
|
* sysdeps/unix/sysv/linux/fork.c: New file.
|
||||||
|
* sysdeps/unix/sysv/linux/fork.h: New file.
|
||||||
|
* sysdeps/unix/sysv/linux/ia64/fork.h: New file.
|
||||||
|
* sysdeps/unix/sysv/linux/sparc/fork.h: New file.
|
||||||
|
* sysdeps/unix/sysv/linux/register-atfork.c: New file.
|
||||||
|
* sysdeps/unix/sysv/linux/unregister-atfork.c: New file.
|
||||||
|
* sysdeps/unix/sysv/linux/Makefile: New file.
|
||||||
|
* sysdeps/unix/sysv/linux/Versions: New file.
|
||||||
|
* ptlongjmp.c (pthread_cleanup_upto): Rename to...
|
||||||
|
(__pthread_cleanup_upto): ...this. Add targetframe argument,
|
||||||
|
use it instead of currentframe. No longer static.
|
||||||
|
(siglongjmp, longjmp): Remove pthread_cleanup_upto calls.
|
||||||
|
* internals.h (__pthread_cleanup_upto, __pthread_fork): New prototypes.
|
||||||
|
(struct pthread_functions): Add ptr_pthread_fork,
|
||||||
|
ptr_pthread_cleanup_upto.
|
||||||
|
* pthread.c (pthread_functions): Initialize ptr_pthread_fork and
|
||||||
|
ptr_pthread_cleanup_upto.
|
||||||
|
* ptfork.c: Include fork.h.
|
||||||
|
(struct handler_list, struct handler_list_block): Remove.
|
||||||
|
(pthread_atfork_lock, pthread_atfork_prepare, pthread_atfork_parent,
|
||||||
|
pthread_atfork_child): Remove.
|
||||||
|
(pthread_insert_list, __pthread_atfork, pthread_call_handlers): Remove.
|
||||||
|
(__pthread_fork): New function.
|
||||||
|
(__fork, __vfork): Call __libc_fork.
|
||||||
|
* Makefile (libpthread-routines): Add old_pthread_atfork.
|
||||||
|
(libpthread-nonshared): Add pthread_atfork.
|
||||||
|
(others): Depend on $(objpfx)libpthread_nonshared.a.
|
||||||
|
($(objpfx)libpthread_nonshared.a): New rule.
|
||||||
|
(install): Depend on $(inst_libdir)/libpthread.so.
|
||||||
|
($(inst_libdir)/libpthread.so, $(inst_libdir)/libpthread_nonshared.a):
|
||||||
|
New rules.
|
||||||
|
(tests): Depend on libpthread_nonshared.a too.
|
||||||
|
* old_pthread_atfork.c: New file.
|
||||||
|
* pthread_atfork.c: New file.
|
||||||
|
* Makeconfig (shared-thread-library): Include libpthread_nonshared.a
|
||||||
|
too.
|
||||||
|
|
||||||
2002-12-30 Jakub Jelinek <jakub@redhat.com>
|
2002-12-30 Jakub Jelinek <jakub@redhat.com>
|
||||||
|
|
||||||
* forward.c: Make all functions available by default again. It
|
* forward.c: Make all functions available by default again. It
|
||||||
|
@ -3,7 +3,8 @@
|
|||||||
|
|
||||||
have-thread-library = yes
|
have-thread-library = yes
|
||||||
|
|
||||||
shared-thread-library = $(common-objpfx)linuxthreads/libpthread.so
|
shared-thread-library = $(common-objpfx)linuxthreads/libpthread.so \
|
||||||
|
$(common-objpfx)linuxthreads/libpthread_nonshared.a
|
||||||
static-thread-library = $(common-objpfx)linuxthreads/libpthread.a
|
static-thread-library = $(common-objpfx)linuxthreads/libpthread.a
|
||||||
bounded-thread-library = $(common-objpfx)linuxthreads/libpthread_b.a
|
bounded-thread-library = $(common-objpfx)linuxthreads/libpthread_b.a
|
||||||
|
|
||||||
|
@ -46,12 +46,14 @@ libpthread-routines := attr cancel condvar join manager mutex ptfork \
|
|||||||
ptw-lseek64 ptw-llseek ptw-msync ptw-nanosleep \
|
ptw-lseek64 ptw-llseek ptw-msync ptw-nanosleep \
|
||||||
ptw-open ptw-open64 ptw-pause ptw-pread ptw-pread64 \
|
ptw-open ptw-open64 ptw-pause ptw-pread ptw-pread64 \
|
||||||
ptw-pwrite ptw-pwrite64 ptw-tcdrain ptw-wait \
|
ptw-pwrite ptw-pwrite64 ptw-tcdrain ptw-wait \
|
||||||
ptw-waitpid pt-system
|
ptw-waitpid pt-system old_pthread_atfork
|
||||||
# Don't generate deps for calls with no sources. See sysdeps/unix/Makefile.
|
# Don't generate deps for calls with no sources. See sysdeps/unix/Makefile.
|
||||||
omit-deps = $(unix-syscalls:%=ptw-%)
|
omit-deps = $(unix-syscalls:%=ptw-%)
|
||||||
|
|
||||||
libpthread-shared-only-routines = pt-allocrtsig
|
libpthread-shared-only-routines = pt-allocrtsig
|
||||||
|
|
||||||
|
libpthread-nonshared = pthread_atfork
|
||||||
|
|
||||||
nodelete-yes = -Wl,--enable-new-dtags,-z,nodelete
|
nodelete-yes = -Wl,--enable-new-dtags,-z,nodelete
|
||||||
initfirst-yes = -Wl,--enable-new-dtags,-z,initfirst
|
initfirst-yes = -Wl,--enable-new-dtags,-z,initfirst
|
||||||
LDFLAGS-pthread.so = $(nodelete-$(have-z-nodelete)) \
|
LDFLAGS-pthread.so = $(nodelete-$(have-z-nodelete)) \
|
||||||
@ -65,6 +67,14 @@ CFLAGS-tst-cancel.c = -fno-inline -fno-inline-functions
|
|||||||
include ../Makeconfig
|
include ../Makeconfig
|
||||||
|
|
||||||
ifeq ($(build-shared),yes)
|
ifeq ($(build-shared),yes)
|
||||||
|
others: $(objpfx)libpthread_nonshared.a
|
||||||
|
endif
|
||||||
|
|
||||||
|
$(objpfx)libpthread_nonshared.a: $(addprefix $(objpfx),$(addsuffix .os,$(libpthread-nonshared)))
|
||||||
|
$(AR) $(ARFLAGS) $@ $^
|
||||||
|
|
||||||
|
ifeq ($(build-shared),yes)
|
||||||
|
|
||||||
extra-objs += crti.o crtn.o
|
extra-objs += crti.o crtn.o
|
||||||
omit-deps += crti crtn
|
omit-deps += crti crtn
|
||||||
|
|
||||||
@ -92,6 +102,31 @@ endif
|
|||||||
|
|
||||||
include ../Rules
|
include ../Rules
|
||||||
|
|
||||||
|
# What we install as libpthread.so for programs to link against is in fact a
|
||||||
|
# link script. It contains references for the various libraries we need.
|
||||||
|
# The libpthread.so object is not complete since some functions are only defined
|
||||||
|
# in libpthread_nonshared.a.
|
||||||
|
# We need to use absolute paths since otherwise local copies (if they exist)
|
||||||
|
# of the files are taken by the linker.
|
||||||
|
install: $(inst_libdir)/libpthread.so
|
||||||
|
$(inst_libdir)/libpthread.so: $(common-objpfx)format.lds \
|
||||||
|
$(objpfx)libpthread.so$(libpthread.so-version) \
|
||||||
|
$(inst_libdir)/$(patsubst %,$(libtype.oS),\
|
||||||
|
$(libprefix)pthread) \
|
||||||
|
$(+force)
|
||||||
|
(echo '/* GNU ld script';\
|
||||||
|
echo ' Use the shared library, but some functions are only in';\
|
||||||
|
echo ' the static library, so try that secondarily. */';\
|
||||||
|
cat $<; \
|
||||||
|
echo 'GROUP ( $(slibdir)/libpthread.so$(libpthread.so-version)' \
|
||||||
|
'$(libdir)/$(patsubst %,$(libtype.oS),$(libprefix)pthread)'\
|
||||||
|
')' \
|
||||||
|
) > $@.new
|
||||||
|
mv -f $@.new $@
|
||||||
|
$(inst_libdir)/libpthread_nonshared.a: $(objpfx)libpthread_nonshared.a
|
||||||
|
$(do-install)
|
||||||
|
|
||||||
|
|
||||||
extra-B-pthread.so = -B$(common-objpfx)linuxthreads/
|
extra-B-pthread.so = -B$(common-objpfx)linuxthreads/
|
||||||
$(objpfx)libpthread.so: $(objpfx)crti.o $(objpfx)crtn.o
|
$(objpfx)libpthread.so: $(objpfx)crti.o $(objpfx)crtn.o
|
||||||
$(objpfx)libpthread.so: +preinit += $(objpfx)crti.o
|
$(objpfx)libpthread.so: +preinit += $(objpfx)crti.o
|
||||||
@ -154,14 +189,16 @@ $(objpfx)libpthread.so: $(libc-link.so) $(common-objpfx)libc_nonshared.a
|
|||||||
ifeq ($(build-shared),yes)
|
ifeq ($(build-shared),yes)
|
||||||
$(addprefix $(objpfx), \
|
$(addprefix $(objpfx), \
|
||||||
$(filter-out $(tests-static) $(tests-reverse) unload, \
|
$(filter-out $(tests-static) $(tests-reverse) unload, \
|
||||||
$(tests) $(test-srcs))): $(objpfx)libpthread.so
|
$(tests) $(test-srcs))): $(objpfx)libpthread.so \
|
||||||
|
$(objpfx)libpthread_nonshared.a
|
||||||
# $(objpfx)../libc.so is used instead of $(common-objpfx)libc.so,
|
# $(objpfx)../libc.so is used instead of $(common-objpfx)libc.so,
|
||||||
# since otherwise libpthread.so comes before libc.so when linking.
|
# since otherwise libpthread.so comes before libc.so when linking.
|
||||||
$(addprefix $(objpfx), $(tests-reverse)): \
|
$(addprefix $(objpfx), $(tests-reverse)): \
|
||||||
$(objpfx)../libc.so $(objpfx)libpthread.so
|
$(objpfx)../libc.so $(objpfx)libpthread.so \
|
||||||
|
$(objpfx)libpthread_nonshared.a
|
||||||
$(addprefix $(objpfx),$(librt-tests)): $(common-objpfx)rt/librt.so
|
$(addprefix $(objpfx),$(librt-tests)): $(common-objpfx)rt/librt.so
|
||||||
$(objpfx)unload: $(common-objpfx)dlfcn/libdl.so
|
$(objpfx)unload: $(common-objpfx)dlfcn/libdl.so
|
||||||
$(objpfx)unload.out: $(objpfx)libpthread.so
|
$(objpfx)unload.out: $(objpfx)libpthread.so $(objpfx)libpthread_nonshared.a
|
||||||
else
|
else
|
||||||
$(addprefix $(objpfx),$(tests) $(test-srcs)): $(objpfx)libpthread.a
|
$(addprefix $(objpfx),$(tests) $(test-srcs)): $(objpfx)libpthread.a
|
||||||
$(addprefix $(objpfx),$(librt-tests)): $(common-objpfx)rt/librt.a
|
$(addprefix $(objpfx),$(librt-tests)): $(common-objpfx)rt/librt.a
|
||||||
|
@ -463,6 +463,11 @@ extern int __libc_enable_asynccancel (void) attribute_hidden;
|
|||||||
extern void __libc_disable_asynccancel (int oldtype)
|
extern void __libc_disable_asynccancel (int oldtype)
|
||||||
internal_function attribute_hidden;
|
internal_function attribute_hidden;
|
||||||
|
|
||||||
|
extern void __pthread_cleanup_upto (__jmp_buf target,
|
||||||
|
char *targetframe) attribute_hidden;
|
||||||
|
struct fork_block;
|
||||||
|
extern pid_t __pthread_fork (struct fork_block *b) attribute_hidden;
|
||||||
|
|
||||||
#if !defined NOT_IN_libc
|
#if !defined NOT_IN_libc
|
||||||
# define LIBC_CANCEL_ASYNC() \
|
# define LIBC_CANCEL_ASYNC() \
|
||||||
__libc_enable_asynccancel ()
|
__libc_enable_asynccancel ()
|
||||||
@ -482,6 +487,7 @@ extern void __libc_disable_asynccancel (int oldtype)
|
|||||||
the thread functions. */
|
the thread functions. */
|
||||||
struct pthread_functions
|
struct pthread_functions
|
||||||
{
|
{
|
||||||
|
pid_t (*ptr_pthread_fork) (struct fork_block *);
|
||||||
int (*ptr_pthread_attr_destroy) (pthread_attr_t *);
|
int (*ptr_pthread_attr_destroy) (pthread_attr_t *);
|
||||||
int (*ptr___pthread_attr_init_2_0) (pthread_attr_t *);
|
int (*ptr___pthread_attr_init_2_0) (pthread_attr_t *);
|
||||||
int (*ptr___pthread_attr_init_2_1) (pthread_attr_t *);
|
int (*ptr___pthread_attr_init_2_1) (pthread_attr_t *);
|
||||||
@ -519,6 +525,8 @@ struct pthread_functions
|
|||||||
int (*ptr_pthread_setcancelstate) (int, int *);
|
int (*ptr_pthread_setcancelstate) (int, int *);
|
||||||
int (*ptr_pthread_setcanceltype) (int, int *);
|
int (*ptr_pthread_setcanceltype) (int, int *);
|
||||||
void (*ptr_pthread_do_exit) (void *retval, char *currentframe);
|
void (*ptr_pthread_do_exit) (void *retval, char *currentframe);
|
||||||
|
void (*ptr_pthread_cleanup_upto) (__jmp_buf target,
|
||||||
|
char *targetframe);
|
||||||
pthread_descr (*ptr_pthread_thread_self) (void);
|
pthread_descr (*ptr_pthread_thread_self) (void);
|
||||||
int (*ptr_pthread_internal_tsd_set) (int key, const void * pointer);
|
int (*ptr_pthread_internal_tsd_set) (int key, const void * pointer);
|
||||||
void * (*ptr_pthread_internal_tsd_get) (int key);
|
void * (*ptr_pthread_internal_tsd_get) (int key);
|
||||||
|
27
linuxthreads/old_pthread_atfork.c
Normal file
27
linuxthreads/old_pthread_atfork.c
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
/* Copyright (C) 2002 Free Software Foundation, Inc.
|
||||||
|
This file is part of the GNU C Library.
|
||||||
|
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
|
||||||
|
|
||||||
|
The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with the GNU C Library; if not, write to the Free
|
||||||
|
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||||
|
02111-1307 USA. */
|
||||||
|
|
||||||
|
#include <shlib-compat.h>
|
||||||
|
|
||||||
|
#if SHLIB_COMPAT (libpthread, GLIBC_2_0, GLIBC_2_3)
|
||||||
|
# define __pthread_atfork __dyn_pthread_atfork
|
||||||
|
# include "pthread_atfork.c"
|
||||||
|
# undef __pthread_atfork
|
||||||
|
compat_symbol (libpthread, __dyn_pthread_atfork, pthread_atfork, GLIBC_2_0);
|
||||||
|
#endif
|
@ -21,96 +21,71 @@
|
|||||||
#include "pthread.h"
|
#include "pthread.h"
|
||||||
#include "internals.h"
|
#include "internals.h"
|
||||||
#include <bits/libc-lock.h>
|
#include <bits/libc-lock.h>
|
||||||
|
#include "fork.h"
|
||||||
struct handler_list {
|
|
||||||
void (*handler)(void);
|
|
||||||
struct handler_list * next;
|
|
||||||
};
|
|
||||||
|
|
||||||
static pthread_mutex_t pthread_atfork_lock = PTHREAD_MUTEX_INITIALIZER;
|
|
||||||
static struct handler_list * pthread_atfork_prepare = NULL;
|
|
||||||
static struct handler_list * pthread_atfork_parent = NULL;
|
|
||||||
static struct handler_list * pthread_atfork_child = NULL;
|
|
||||||
|
|
||||||
static void pthread_insert_list(struct handler_list ** list,
|
|
||||||
void (*handler)(void),
|
|
||||||
struct handler_list * newlist,
|
|
||||||
int at_end)
|
|
||||||
{
|
|
||||||
if (handler == NULL) return;
|
|
||||||
if (at_end) {
|
|
||||||
while(*list != NULL) list = &((*list)->next);
|
|
||||||
}
|
|
||||||
newlist->handler = handler;
|
|
||||||
newlist->next = *list;
|
|
||||||
*list = newlist;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct handler_list_block {
|
|
||||||
struct handler_list prepare, parent, child;
|
|
||||||
};
|
|
||||||
|
|
||||||
int __pthread_atfork(void (*prepare)(void),
|
|
||||||
void (*parent)(void),
|
|
||||||
void (*child)(void))
|
|
||||||
{
|
|
||||||
struct handler_list_block * block =
|
|
||||||
(struct handler_list_block *) malloc(sizeof(struct handler_list_block));
|
|
||||||
if (block == NULL) return ENOMEM;
|
|
||||||
pthread_mutex_lock(&pthread_atfork_lock);
|
|
||||||
/* "prepare" handlers are called in LIFO */
|
|
||||||
pthread_insert_list(&pthread_atfork_prepare, prepare, &block->prepare, 0);
|
|
||||||
/* "parent" handlers are called in FIFO */
|
|
||||||
pthread_insert_list(&pthread_atfork_parent, parent, &block->parent, 1);
|
|
||||||
/* "child" handlers are called in FIFO */
|
|
||||||
pthread_insert_list(&pthread_atfork_child, child, &block->child, 1);
|
|
||||||
pthread_mutex_unlock(&pthread_atfork_lock);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
strong_alias (__pthread_atfork, pthread_atfork)
|
|
||||||
|
|
||||||
static inline void pthread_call_handlers(struct handler_list * list)
|
|
||||||
{
|
|
||||||
for (/*nothing*/; list != NULL; list = list->next) (list->handler)();
|
|
||||||
}
|
|
||||||
|
|
||||||
extern int __libc_fork (void);
|
extern int __libc_fork (void);
|
||||||
|
|
||||||
pid_t __fork(void)
|
pid_t __pthread_fork (struct fork_block *b)
|
||||||
{
|
{
|
||||||
pid_t pid;
|
pid_t pid;
|
||||||
|
list_t *runp;
|
||||||
|
|
||||||
pthread_mutex_lock(&pthread_atfork_lock);
|
__libc_lock_lock (b->lock);
|
||||||
|
|
||||||
|
/* Run all the registered preparation handlers. In reverse order. */
|
||||||
|
list_for_each_prev (runp, &b->prepare_list)
|
||||||
|
{
|
||||||
|
struct fork_handler *curp;
|
||||||
|
curp = list_entry (runp, struct fork_handler, list);
|
||||||
|
curp->handler ();
|
||||||
|
}
|
||||||
|
|
||||||
pthread_call_handlers(pthread_atfork_prepare);
|
|
||||||
__pthread_once_fork_prepare();
|
__pthread_once_fork_prepare();
|
||||||
__flockfilelist();
|
__flockfilelist();
|
||||||
|
|
||||||
pid = __libc_fork();
|
pid = ARCH_FORK ();
|
||||||
|
|
||||||
if (pid == 0) {
|
if (pid == 0) {
|
||||||
__pthread_reset_main_thread();
|
__pthread_reset_main_thread();
|
||||||
|
|
||||||
__fresetlockfiles();
|
__fresetlockfiles();
|
||||||
__pthread_once_fork_child();
|
__pthread_once_fork_child();
|
||||||
pthread_call_handlers(pthread_atfork_child);
|
|
||||||
|
|
||||||
pthread_mutex_init(&pthread_atfork_lock, NULL);
|
/* Run the handlers registered for the child. */
|
||||||
|
list_for_each (runp, &b->child_list)
|
||||||
|
{
|
||||||
|
struct fork_handler *curp;
|
||||||
|
curp = list_entry (runp, struct fork_handler, list);
|
||||||
|
curp->handler ();
|
||||||
|
}
|
||||||
|
|
||||||
|
__libc_lock_init (b->lock);
|
||||||
} else {
|
} else {
|
||||||
__funlockfilelist();
|
__funlockfilelist();
|
||||||
__pthread_once_fork_parent();
|
__pthread_once_fork_parent();
|
||||||
pthread_call_handlers(pthread_atfork_parent);
|
|
||||||
|
|
||||||
pthread_mutex_unlock(&pthread_atfork_lock);
|
/* Run the handlers registered for the parent. */
|
||||||
|
list_for_each (runp, &b->parent_list)
|
||||||
|
{
|
||||||
|
struct fork_handler *curp;
|
||||||
|
curp = list_entry (runp, struct fork_handler, list);
|
||||||
|
curp->handler ();
|
||||||
|
}
|
||||||
|
|
||||||
|
__libc_lock_unlock (b->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
return pid;
|
return pid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pid_t __fork (void)
|
||||||
|
{
|
||||||
|
return __libc_fork ();
|
||||||
|
}
|
||||||
weak_alias (__fork, fork);
|
weak_alias (__fork, fork);
|
||||||
|
|
||||||
pid_t __vfork(void)
|
pid_t __vfork(void)
|
||||||
{
|
{
|
||||||
return __fork();
|
return __libc_fork ();
|
||||||
}
|
}
|
||||||
weak_alias (__vfork, vfork);
|
weak_alias (__vfork, vfork);
|
||||||
|
@ -238,6 +238,7 @@ static struct pthread_functions pthread_functions =
|
|||||||
.ptr_pthread_internal_tsd_get = __pthread_internal_tsd_get,
|
.ptr_pthread_internal_tsd_get = __pthread_internal_tsd_get,
|
||||||
.ptr_pthread_internal_tsd_address = __pthread_internal_tsd_address,
|
.ptr_pthread_internal_tsd_address = __pthread_internal_tsd_address,
|
||||||
#endif
|
#endif
|
||||||
|
.ptr_pthread_fork = __pthread_fork,
|
||||||
.ptr_pthread_attr_destroy = __pthread_attr_destroy,
|
.ptr_pthread_attr_destroy = __pthread_attr_destroy,
|
||||||
#if SHLIB_COMPAT(libpthread, GLIBC_2_0, GLIBC_2_1)
|
#if SHLIB_COMPAT(libpthread, GLIBC_2_0, GLIBC_2_1)
|
||||||
.ptr___pthread_attr_init_2_0 = __pthread_attr_init_2_0,
|
.ptr___pthread_attr_init_2_0 = __pthread_attr_init_2_0,
|
||||||
@ -273,7 +274,8 @@ static struct pthread_functions pthread_functions =
|
|||||||
.ptr_pthread_setcancelstate = __pthread_setcancelstate,
|
.ptr_pthread_setcancelstate = __pthread_setcancelstate,
|
||||||
.ptr_pthread_setcanceltype = __pthread_setcanceltype,
|
.ptr_pthread_setcanceltype = __pthread_setcanceltype,
|
||||||
.ptr_pthread_do_exit = __pthread_do_exit,
|
.ptr_pthread_do_exit = __pthread_do_exit,
|
||||||
.ptr_pthread_thread_self = __pthread_thread_self
|
.ptr_pthread_thread_self = __pthread_thread_self,
|
||||||
|
.ptr_pthread_cleanup_upto = __pthread_cleanup_upto
|
||||||
};
|
};
|
||||||
# define ptr_pthread_functions &pthread_functions
|
# define ptr_pthread_functions &pthread_functions
|
||||||
#else
|
#else
|
||||||
|
46
linuxthreads/pthread_atfork.c
Normal file
46
linuxthreads/pthread_atfork.c
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
/* Copyright (C) 2002 Free Software Foundation, Inc.
|
||||||
|
This file is part of the GNU C Library.
|
||||||
|
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
|
||||||
|
|
||||||
|
The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with the GNU C Library; if not, write to the Free
|
||||||
|
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||||
|
02111-1307 USA. */
|
||||||
|
|
||||||
|
#include "internals.h"
|
||||||
|
#include <fork.h>
|
||||||
|
|
||||||
|
/* This is defined by newer gcc version unique for each module. */
|
||||||
|
extern void *__dso_handle __attribute__ ((__weak__));
|
||||||
|
|
||||||
|
|
||||||
|
/* Hide the symbol so that no definition but the one locally in the
|
||||||
|
executable or DSO is used. */
|
||||||
|
int
|
||||||
|
#ifndef __pthread_atfork
|
||||||
|
/* Don't mark the compatibility function as hidden. */
|
||||||
|
attribute_hidden
|
||||||
|
#endif
|
||||||
|
__pthread_atfork (prepare, parent, child)
|
||||||
|
void (*prepare) (void);
|
||||||
|
void (*parent) (void);
|
||||||
|
void (*child) (void);
|
||||||
|
{
|
||||||
|
return __register_atfork (prepare, parent, child,
|
||||||
|
&__dso_handle == NULL ? NULL : __dso_handle);
|
||||||
|
}
|
||||||
|
#ifndef __pthread_atfork
|
||||||
|
extern int pthread_atfork (void (*prepare) (void), void (*parent) (void),
|
||||||
|
void (*child) (void)) attribute_hidden;
|
||||||
|
strong_alias (__pthread_atfork, pthread_atfork)
|
||||||
|
#endif
|
@ -27,24 +27,23 @@ extern void __libc_longjmp (sigjmp_buf env, int val)
|
|||||||
__attribute__ ((noreturn));
|
__attribute__ ((noreturn));
|
||||||
|
|
||||||
|
|
||||||
static void pthread_cleanup_upto(__jmp_buf target)
|
void __pthread_cleanup_upto (__jmp_buf target, char *targetframe)
|
||||||
{
|
{
|
||||||
pthread_descr self = thread_self();
|
pthread_descr self = thread_self();
|
||||||
struct _pthread_cleanup_buffer * c;
|
struct _pthread_cleanup_buffer * c;
|
||||||
char *currentframe = CURRENT_STACK_FRAME;
|
|
||||||
|
|
||||||
for (c = THREAD_GETMEM(self, p_cleanup);
|
for (c = THREAD_GETMEM(self, p_cleanup);
|
||||||
c != NULL && _JMPBUF_UNWINDS(target, c);
|
c != NULL && _JMPBUF_UNWINDS(target, c);
|
||||||
c = c->__prev)
|
c = c->__prev)
|
||||||
{
|
{
|
||||||
#if _STACK_GROWS_DOWN
|
#if _STACK_GROWS_DOWN
|
||||||
if ((char *) c <= currentframe)
|
if ((char *) c <= targetframe)
|
||||||
{
|
{
|
||||||
c = NULL;
|
c = NULL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#elif _STACK_GROWS_UP
|
#elif _STACK_GROWS_UP
|
||||||
if ((char *) c >= currentframe)
|
if ((char *) c >= targetframe)
|
||||||
{
|
{
|
||||||
c = NULL;
|
c = NULL;
|
||||||
break;
|
break;
|
||||||
@ -62,12 +61,10 @@ static void pthread_cleanup_upto(__jmp_buf target)
|
|||||||
|
|
||||||
void siglongjmp (sigjmp_buf env, int val)
|
void siglongjmp (sigjmp_buf env, int val)
|
||||||
{
|
{
|
||||||
pthread_cleanup_upto(env->__jmpbuf);
|
|
||||||
__libc_siglongjmp (env, val);
|
__libc_siglongjmp (env, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
void longjmp (jmp_buf env, int val)
|
void longjmp (jmp_buf env, int val)
|
||||||
{
|
{
|
||||||
pthread_cleanup_upto(env->__jmpbuf);
|
|
||||||
__libc_longjmp (env, val);
|
__libc_longjmp (env, val);
|
||||||
}
|
}
|
||||||
|
116
linuxthreads/sysdeps/pthread/list.h
Normal file
116
linuxthreads/sysdeps/pthread/list.h
Normal file
@ -0,0 +1,116 @@
|
|||||||
|
/* Copyright (C) 2002 Free Software Foundation, Inc.
|
||||||
|
This file is part of the GNU C Library.
|
||||||
|
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
|
||||||
|
|
||||||
|
The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with the GNU C Library; if not, write to the Free
|
||||||
|
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||||
|
02111-1307 USA. */
|
||||||
|
|
||||||
|
#ifndef _LIST_H
|
||||||
|
#define _LIST_H 1
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
/* The definitions of this file are adopted from those which can be
|
||||||
|
found in the Linux kernel headers to enable people familiar with
|
||||||
|
the latter find their way in these sources as well. */
|
||||||
|
|
||||||
|
|
||||||
|
/* Basic type for the double-link list. */
|
||||||
|
typedef struct list_head
|
||||||
|
{
|
||||||
|
struct list_head *next;
|
||||||
|
struct list_head *prev;
|
||||||
|
} list_t;
|
||||||
|
|
||||||
|
|
||||||
|
/* Define a variable with the head and tail of the list. */
|
||||||
|
#define LIST_HEAD(name) \
|
||||||
|
list_t name = { &(name), &(name) }
|
||||||
|
|
||||||
|
/* Initialize a new list head. */
|
||||||
|
#define INIT_LIST_HEAD(ptr) \
|
||||||
|
(ptr)->next = (ptr)->prev = (ptr)
|
||||||
|
|
||||||
|
|
||||||
|
/* Add new element at the head of the list. */
|
||||||
|
static inline void
|
||||||
|
list_add (list_t *newp, list_t *head)
|
||||||
|
{
|
||||||
|
head->next->prev = newp;
|
||||||
|
newp->next = head->next;
|
||||||
|
newp->prev = head;
|
||||||
|
head->next = newp;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Add new element at the tail of the list. */
|
||||||
|
static inline void
|
||||||
|
list_add_tail (list_t *newp, list_t *head)
|
||||||
|
{
|
||||||
|
head->prev->next = newp;
|
||||||
|
newp->next = head;
|
||||||
|
newp->prev = head->prev;
|
||||||
|
head->prev = newp;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Remove element from list. */
|
||||||
|
static inline void
|
||||||
|
list_del (list_t *elem)
|
||||||
|
{
|
||||||
|
elem->next->prev = elem->prev;
|
||||||
|
elem->prev->next = elem->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Join two lists. */
|
||||||
|
static inline void
|
||||||
|
list_splice (list_t *add, list_t *head)
|
||||||
|
{
|
||||||
|
/* Do nothing if the list which gets added is empty. */
|
||||||
|
if (add != add->next)
|
||||||
|
{
|
||||||
|
add->next->prev = head;
|
||||||
|
add->prev->next = head->next;
|
||||||
|
head->next->prev = add->prev;
|
||||||
|
head->next = add->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Get typed element from list at a given position. */
|
||||||
|
#define list_entry(ptr, type, member) \
|
||||||
|
((type *) ((char *) (ptr) - (unsigned long) (&((type *) 0)->member)))
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* Iterate forward over the elements of the list. */
|
||||||
|
#define list_for_each(pos, head) \
|
||||||
|
for (pos = (head)->next; pos != (head); pos = pos->next)
|
||||||
|
|
||||||
|
|
||||||
|
/* Iterate forward over the elements of the list. */
|
||||||
|
#define list_for_each_prev(pos, head) \
|
||||||
|
for (pos = (head)->prev; pos != (head); pos = pos->prev)
|
||||||
|
|
||||||
|
|
||||||
|
/* Iterate backwards over the elements list. The list elements can be
|
||||||
|
removed from the list while doing this. */
|
||||||
|
#define list_for_each_prev_safe(pos, p, head) \
|
||||||
|
for (pos = (head)->prev, p = pos->prev; \
|
||||||
|
pos != (head); \
|
||||||
|
pos = p, p = pos->prev)
|
||||||
|
|
||||||
|
#endif /* list.h */
|
3
linuxthreads/sysdeps/unix/sysv/linux/Makefile
Normal file
3
linuxthreads/sysdeps/unix/sysv/linux/Makefile
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
ifeq ($(subdir),linuxthreads)
|
||||||
|
sysdep_routines += register-atfork unregister-atfork
|
||||||
|
endif
|
5
linuxthreads/sysdeps/unix/sysv/linux/Versions
Normal file
5
linuxthreads/sysdeps/unix/sysv/linux/Versions
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
libc {
|
||||||
|
GLIBC_2.3.2 {
|
||||||
|
__register_atfork;
|
||||||
|
}
|
||||||
|
}
|
40
linuxthreads/sysdeps/unix/sysv/linux/fork.c
Normal file
40
linuxthreads/sysdeps/unix/sysv/linux/fork.c
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
/* Copyright (C) 2002 Free Software Foundation, Inc.
|
||||||
|
This file is part of the GNU C Library.
|
||||||
|
Contributed by Jakub Jelinek <jakub@redhat.com>, 2002.
|
||||||
|
|
||||||
|
The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with the GNU C Library; if not, write to the Free
|
||||||
|
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||||
|
02111-1307 USA. */
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include "fork.h"
|
||||||
|
#include <bits/libc-lock.h>
|
||||||
|
|
||||||
|
weak_extern (__pthread_fork);
|
||||||
|
|
||||||
|
struct fork_block __fork_block =
|
||||||
|
{
|
||||||
|
.lock = PTHREAD_MUTEX_INITIALIZER,
|
||||||
|
.prepare_list = { &__fork_block.prepare_list, &__fork_block.prepare_list },
|
||||||
|
.parent_list = { &__fork_block.parent_list, &__fork_block.parent_list },
|
||||||
|
.child_list = { &__fork_block.child_list, &__fork_block.child_list }
|
||||||
|
};
|
||||||
|
|
||||||
|
pid_t
|
||||||
|
__libc_fork (void)
|
||||||
|
{
|
||||||
|
return __libc_maybe_call2 (pthread_fork, (&__fork_block), ARCH_FORK ());
|
||||||
|
}
|
||||||
|
weak_alias (__libc_fork, __fork)
|
||||||
|
weak_alias (__libc_fork, fork)
|
59
linuxthreads/sysdeps/unix/sysv/linux/fork.h
Normal file
59
linuxthreads/sysdeps/unix/sysv/linux/fork.h
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
/* Copyright (C) 2002 Free Software Foundation, Inc.
|
||||||
|
This file is part of the GNU C Library.
|
||||||
|
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
|
||||||
|
|
||||||
|
The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with the GNU C Library; if not, write to the Free
|
||||||
|
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||||
|
02111-1307 USA. */
|
||||||
|
|
||||||
|
#include <list.h>
|
||||||
|
#include <bits/libc-lock.h>
|
||||||
|
#include <sysdep.h>
|
||||||
|
|
||||||
|
struct fork_block
|
||||||
|
{
|
||||||
|
/* Lock to protect handling of fork handlers. */
|
||||||
|
__libc_lock_define (, lock);
|
||||||
|
|
||||||
|
/* Lists of registered fork handlers. */
|
||||||
|
list_t prepare_list;
|
||||||
|
list_t parent_list;
|
||||||
|
list_t child_list;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern struct fork_block __fork_block attribute_hidden;
|
||||||
|
|
||||||
|
/* Elements of the fork handler lists. */
|
||||||
|
struct fork_handler
|
||||||
|
{
|
||||||
|
list_t list;
|
||||||
|
void (*handler) (void);
|
||||||
|
void *dso_handle;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/* Function to call to unregister fork handlers. */
|
||||||
|
extern void __unregister_atfork (void *dso_handle) attribute_hidden;
|
||||||
|
#define UNREGISTER_ATFORK(dso_handle) __unregister_atfork (dso_handle)
|
||||||
|
|
||||||
|
|
||||||
|
/* C library side function to register new fork handlers. */
|
||||||
|
extern int __register_atfork (void (*__prepare) (void),
|
||||||
|
void (*__parent) (void),
|
||||||
|
void (*__child) (void),
|
||||||
|
void *dso_handle);
|
||||||
|
|
||||||
|
#ifndef ARCH_FORK
|
||||||
|
# define ARCH_FORK() INLINE_SYSCALL (fork, 0)
|
||||||
|
#endif
|
25
linuxthreads/sysdeps/unix/sysv/linux/ia64/fork.h
Normal file
25
linuxthreads/sysdeps/unix/sysv/linux/ia64/fork.h
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
/* Copyright (C) 2002 Free Software Foundation, Inc.
|
||||||
|
This file is part of the GNU C Library.
|
||||||
|
Contributed by Jakub Jelinek <jakub@redhat.com>, 2002.
|
||||||
|
|
||||||
|
The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with the GNU C Library; if not, write to the Free
|
||||||
|
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||||
|
02111-1307 USA. */
|
||||||
|
|
||||||
|
#include <signal.h>
|
||||||
|
#include <sysdep.h>
|
||||||
|
|
||||||
|
#define ARCH_FORK() INLINE_SYSCALL (clone, 2, SIGCHLD, 0)
|
||||||
|
|
||||||
|
#include_next <fork.h>
|
32
linuxthreads/sysdeps/unix/sysv/linux/jmp-unwind.c
Normal file
32
linuxthreads/sysdeps/unix/sysv/linux/jmp-unwind.c
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
/* _longjmp_unwind -- Clean up stack frames unwound by longjmp.
|
||||||
|
Copyright (C) 2002 Free Software Foundation, Inc.
|
||||||
|
This file is part of the GNU C Library.
|
||||||
|
|
||||||
|
The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with the GNU C Library; if not, write to the Free
|
||||||
|
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||||
|
02111-1307 USA. */
|
||||||
|
|
||||||
|
#include <setjmp.h>
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <bits/libc-lock.h>
|
||||||
|
|
||||||
|
weak_extern (__pthread_cleanup_upto);
|
||||||
|
|
||||||
|
void
|
||||||
|
_longjmp_unwind (jmp_buf env, int val)
|
||||||
|
{
|
||||||
|
__libc_maybe_call2 (pthread_cleanup_upto,
|
||||||
|
(env->__jmpbuf, __builtin_frame_address (0)),
|
||||||
|
(void) 0);
|
||||||
|
}
|
87
linuxthreads/sysdeps/unix/sysv/linux/register-atfork.c
Normal file
87
linuxthreads/sysdeps/unix/sysv/linux/register-atfork.c
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
/* Copyright (C) 2002 Free Software Foundation, Inc.
|
||||||
|
This file is part of the GNU C Library.
|
||||||
|
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
|
||||||
|
|
||||||
|
The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with the GNU C Library; if not, write to the Free
|
||||||
|
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||||
|
02111-1307 USA. */
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "fork.h"
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
__register_atfork (prepare, parent, child, dso_handle)
|
||||||
|
void (*prepare) (void);
|
||||||
|
void (*parent) (void);
|
||||||
|
void (*child) (void);
|
||||||
|
void *dso_handle;
|
||||||
|
{
|
||||||
|
struct fork_handler *new_prepare = NULL;
|
||||||
|
struct fork_handler *new_parent = NULL;
|
||||||
|
struct fork_handler *new_child = NULL;
|
||||||
|
|
||||||
|
if (prepare != NULL)
|
||||||
|
{
|
||||||
|
new_prepare = (struct fork_handler *) malloc (sizeof (*new_prepare));
|
||||||
|
if (new_prepare == NULL)
|
||||||
|
goto out1;
|
||||||
|
|
||||||
|
new_prepare->handler = prepare;
|
||||||
|
new_prepare->dso_handle = dso_handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (parent != NULL)
|
||||||
|
{
|
||||||
|
new_parent = (struct fork_handler *) malloc (sizeof (*new_parent));
|
||||||
|
if (new_parent == NULL)
|
||||||
|
goto out2;
|
||||||
|
|
||||||
|
new_parent->handler = parent;
|
||||||
|
new_parent->dso_handle = dso_handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (child != NULL)
|
||||||
|
{
|
||||||
|
new_child = (struct fork_handler *) malloc (sizeof (*new_child));
|
||||||
|
if (new_child == NULL)
|
||||||
|
{
|
||||||
|
free (new_parent);
|
||||||
|
out2:
|
||||||
|
free (new_prepare);
|
||||||
|
out1:
|
||||||
|
return errno;
|
||||||
|
}
|
||||||
|
|
||||||
|
new_child->handler = child;
|
||||||
|
new_child->dso_handle = dso_handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get the lock to not conflict with running forks. */
|
||||||
|
__libc_lock_lock (__fork_block.lock);
|
||||||
|
|
||||||
|
/* Now that we have all the handlers allocate enqueue them. */
|
||||||
|
if (new_prepare != NULL)
|
||||||
|
list_add_tail (&new_prepare->list, &__fork_block.prepare_list);
|
||||||
|
if (new_parent != NULL)
|
||||||
|
list_add_tail (&new_parent->list, &__fork_block.parent_list);
|
||||||
|
if (new_child != NULL)
|
||||||
|
list_add_tail (&new_child->list, &__fork_block.child_list);
|
||||||
|
|
||||||
|
/* Release the lock. */
|
||||||
|
__libc_lock_unlock (__fork_block.lock);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
34
linuxthreads/sysdeps/unix/sysv/linux/sparc/fork.h
Normal file
34
linuxthreads/sysdeps/unix/sysv/linux/sparc/fork.h
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
/* Copyright (C) 2002 Free Software Foundation, Inc.
|
||||||
|
This file is part of the GNU C Library.
|
||||||
|
Contributed by Jakub Jelinek <jakub@redhat.com>, 2002.
|
||||||
|
|
||||||
|
The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with the GNU C Library; if not, write to the Free
|
||||||
|
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||||
|
02111-1307 USA. */
|
||||||
|
|
||||||
|
#include <sysdep.h>
|
||||||
|
|
||||||
|
#define ARCH_FORK() \
|
||||||
|
({ \
|
||||||
|
register long __o0 __asm__ ("o0"); \
|
||||||
|
register long __o1 __asm__ ("o1"); \
|
||||||
|
register long __g1 __asm__ ("g1") = __NR_fork; \
|
||||||
|
__asm __volatile (__SYSCALL_STRING \
|
||||||
|
: "=r" (__g1), "=r" (__o0), "=r" (__o1) \
|
||||||
|
: "0" (__g1) \
|
||||||
|
: __SYSCALL_CLOBBERS); \
|
||||||
|
__o0 == -1 ? __o0 : (__o0 & (__o1 - 1)); \
|
||||||
|
})
|
||||||
|
|
||||||
|
#include_next <fork.h>
|
49
linuxthreads/sysdeps/unix/sysv/linux/unregister-atfork.c
Normal file
49
linuxthreads/sysdeps/unix/sysv/linux/unregister-atfork.c
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
/* Copyright (C) 2002 Free Software Foundation, Inc.
|
||||||
|
This file is part of the GNU C Library.
|
||||||
|
Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
|
||||||
|
|
||||||
|
The GNU C Library is free software; you can redistribute it and/or
|
||||||
|
modify it under the terms of the GNU Lesser General Public
|
||||||
|
License as published by the Free Software Foundation; either
|
||||||
|
version 2.1 of the License, or (at your option) any later version.
|
||||||
|
|
||||||
|
The GNU C Library is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
Lesser General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU Lesser General Public
|
||||||
|
License along with the GNU C Library; if not, write to the Free
|
||||||
|
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
|
||||||
|
02111-1307 USA. */
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "fork.h"
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
__unregister_atfork (dso_handle)
|
||||||
|
void *dso_handle;
|
||||||
|
{
|
||||||
|
/* Get the lock to not conflict with running forks. */
|
||||||
|
__libc_lock_lock (__fork_block.lock);
|
||||||
|
|
||||||
|
list_t *runp;
|
||||||
|
list_t *prevp;
|
||||||
|
|
||||||
|
list_for_each_prev_safe (runp, prevp, &__fork_block.prepare_list)
|
||||||
|
if (list_entry (runp, struct fork_handler, list)->dso_handle == dso_handle)
|
||||||
|
list_del (runp);
|
||||||
|
|
||||||
|
list_for_each_prev_safe (runp, prevp, &__fork_block.parent_list)
|
||||||
|
if (list_entry (runp, struct fork_handler, list)->dso_handle == dso_handle)
|
||||||
|
list_del (runp);
|
||||||
|
|
||||||
|
list_for_each_prev_safe (runp, prevp, &__fork_block.child_list)
|
||||||
|
if (list_entry (runp, struct fork_handler, list)->dso_handle == dso_handle)
|
||||||
|
list_del (runp);
|
||||||
|
|
||||||
|
/* Release the lock. */
|
||||||
|
__libc_lock_unlock (__fork_block.lock);
|
||||||
|
}
|
@ -72,8 +72,14 @@ __libc_lock_define (typedef, mutex_t)
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* This is defined by newer gcc version unique for each module. */
|
||||||
|
extern void *__dso_handle __attribute__ ((__weak__));
|
||||||
|
|
||||||
|
#include <fork.h>
|
||||||
|
|
||||||
#define thread_atfork(prepare, parent, child) \
|
#define thread_atfork(prepare, parent, child) \
|
||||||
(__pthread_atfork != NULL ? __pthread_atfork(prepare, parent, child) : 0)
|
__register_atfork (prepare, parent, child, \
|
||||||
|
&__dso_handle == NULL ? NULL : __dso_handle)
|
||||||
|
|
||||||
#elif defined(MUTEX_INITIALIZER)
|
#elif defined(MUTEX_INITIALIZER)
|
||||||
/* Assume hurd, with cthreads */
|
/* Assume hurd, with cthreads */
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
2002-12-30 Ulrich Drepper <drepper@redhat.com>
|
2002-12-30 Ulrich Drepper <drepper@redhat.com>
|
||||||
|
|
||||||
|
* sysdeps/pthread/pt-initfini.c (call_initialize_minimal): Mark
|
||||||
|
__pthread_initialize_minimal as hidden.
|
||||||
|
|
||||||
* init.c (__pthread_initialize_minimal_internal): Don't mark as
|
* init.c (__pthread_initialize_minimal_internal): Don't mark as
|
||||||
constructor.
|
constructor.
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* Special .init and .fini section support. Linuxthread version.
|
/* Special .init and .fini section support. Linuxthread version.
|
||||||
Copyright (C) 1995, 1996, 1997, 2000, 2001 Free Software Foundation, Inc.
|
Copyright (C) 1995,1996,1997,2000,2001,2002 Free Software Foundation, Inc.
|
||||||
This file is part of the GNU C Library.
|
This file is part of the GNU C Library.
|
||||||
|
|
||||||
The GNU C Library is free software; you can redistribute it
|
The GNU C Library is free software; you can redistribute it
|
||||||
@ -65,7 +65,8 @@ asm ("\n/*@_init_PROLOG_BEGINS*/");
|
|||||||
static void
|
static void
|
||||||
call_initialize_minimal (void)
|
call_initialize_minimal (void)
|
||||||
{
|
{
|
||||||
extern void __pthread_initialize_minimal (void);
|
extern void __pthread_initialize_minimal (void)
|
||||||
|
__attribute ((visibility ("hidden")));
|
||||||
|
|
||||||
__pthread_initialize_minimal ();
|
__pthread_initialize_minimal ();
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user