diff options
-rw-r--r-- | devel/linuxthreads/Makefile | 12 | ||||
-rw-r--r-- | devel/linuxthreads/files/README.FreeBSD | 22 | ||||
-rw-r--r-- | devel/linuxthreads/files/patch-aa | 29 |
3 files changed, 56 insertions, 7 deletions
diff --git a/devel/linuxthreads/Makefile b/devel/linuxthreads/Makefile index c59906b0cacc..757132aa2403 100644 --- a/devel/linuxthreads/Makefile +++ b/devel/linuxthreads/Makefile @@ -7,7 +7,7 @@ PORTNAME= linuxthreads PORTVERSION= 2.2.3 -PORTREVISION= 9 +PORTREVISION= 10 CATEGORIES= devel MASTER_SITES= ${MASTER_SITE_GNU} MASTER_SITE_SUBDIR= glibc @@ -30,6 +30,9 @@ MAKE_ENV+= USING_GCC3=true .if defined(INSTALL_LIBLTHREAD_PIC_ARCHIVE) MAKE_ENV+= INSTALL_LIBLTHREAD_PIC_ARCHIVE=yes .endif +.if defined(LINUXTHREADS_DETECT_UNSAFE_EXIT) +MAKE_ENV+= LINUXTHREADS_DETECT_UNSAFE_EXIT=yes +.endif threads_files := README.FreeBSD clone.S clone.h freebsd-compat.h getgr_r.c \ gethostby_r.c getnetby_r.c getprotoby_r.c getpw_r.c getservby_r.c \ @@ -48,6 +51,13 @@ pre-fetch: @${ECHO} WITH_CONDWAIT_PATCH @${ECHO} .endif +.if !defined(LINUXTHREADS_DETECT_UNSAFE_EXIT) + @${ECHO} + @${ECHO} "Some unsafe calls to exit() can be detected by defining" + @${ECHO} "LINUXTHREADS_DETECT_UNSAFE_EXIT, see files/README.FreeBSD" + @${ECHO} "for more info." + @${ECHO} +.endif @if ${TEST} -f /usr/src/gnu/lib/libgcc/Makefile; then \ : ; \ else \ diff --git a/devel/linuxthreads/files/README.FreeBSD b/devel/linuxthreads/files/README.FreeBSD index 8cd203c2dca7..31b59b43b2b4 100644 --- a/devel/linuxthreads/files/README.FreeBSD +++ b/devel/linuxthreads/files/README.FreeBSD @@ -90,3 +90,25 @@ set at 20 + 16 * MAXUSERS. initializers. Linking the shared linuxthreads library before any such library causes the liblgcc_r.a version of those functions to be used. Use liblstdc++ and liblsupc++. + +4) Exit handling is broken. + + If the linuxthreads library has been compiled with + LINUXTHREADS_DETECT_UNSAFE_EXIT defined in the ports makefile then + the library tries to avoid further calls to functions registered + with atexit if not called from the main thread or if other threads + were active. Since this implicitly indicates a failure to do + proper cleanup, the exit code is then changed to 1. + + If the linuxthreads library has been compiled without + LINUXTHREADS_DETECT_UNSAFE_EXIT, then calls to exit() has a + slightly higher probability of crashing or hanging the program when + other threads are active. If another thread than the main thread + performs the exit call, the exit code will appear to be 0. + + If multiple threads calls exit then the application will likely + crash. + + If other threads has been joined by the main thread before it calls + exit then exit handling should be fairly safe and the correct exit + code can be detected by the parent process. diff --git a/devel/linuxthreads/files/patch-aa b/devel/linuxthreads/files/patch-aa index ecb387fc7983..e0a30bfaa397 100644 --- a/devel/linuxthreads/files/patch-aa +++ b/devel/linuxthreads/files/patch-aa @@ -13,7 +13,7 @@ diff -ru ../../work/linuxthreads-2.2.3/Examples/Makefile ./Examples/Makefile diff -ru ../../work/linuxthreads-2.2.3/Makefile ./Makefile --- ../../work/linuxthreads-2.2.3/Makefile Wed Apr 25 21:50:59 2001 +++ ./Makefile Thu Jun 7 23:13:52 2001 -@@ -1,128 +1,88 @@ +@@ -1,128 +1,91 @@ -# Copyright (C) 1996,1997,1998,1999,2000,2001 Free Software Foundation, Inc. -# This file is part of the GNU C Library. +LIB=lthread @@ -57,6 +57,9 @@ diff -ru ../../work/linuxthreads-2.2.3/Makefile ./Makefile +CFLAGS += -DLINUXTHREADS +CFLAGS += -D__USE_UNIX98 +CFLAGS += -D__USE_XOPEN2K -D_STACK_GROWS_DOWN -DNEWLIBC -D_THREAD_SAFE ++.if defined(LINUXTHREADS_DETECT_UNSAFE_EXIT) ++CFLAGS += -DLINUXTHREADS_DETECT_UNSAFE_EXIT ++.endif + +AINC = -I${LIBSRC_BASE}/libc/${MACHINE_ARCH} -I${.CURDIR}/sysdeps/${MACHINE_ARCH} + @@ -513,32 +516,38 @@ diff -ru ../../work/linuxthreads-2.2.3/manager.c ./manager.c detached = th->p_detached; __pthread_unlock(th->p_lock); if (detached) -@@ -834,10 +857,16 @@ +@@ -834,10 +857,20 @@ /* Process-wide exit() */ ++#ifdef LINUXTHREADS_DETECT_UNSAFE_EXIT +extern int __pthread_exit_requested_bymainthread; +extern int __pthread_exit_alone; ++#endif + static void pthread_handle_exit(pthread_descr issuing_thread, int exitcode) { pthread_descr th; __pthread_exit_requested = 1; ++#ifdef LINUXTHREADS_DETECT_UNSAFE_EXIT + __pthread_exit_alone = 1; + if (issuing_thread == __pthread_main_thread) + __pthread_exit_requested_bymainthread = 1; ++#endif __pthread_exit_code = exitcode; /* Send the CANCEL signal to all running threads, including the main thread, but excluding the thread from which the exit request originated -@@ -846,6 +875,11 @@ +@@ -846,6 +875,13 @@ for (th = issuing_thread->p_nextlive; th != issuing_thread; th = th->p_nextlive) { ++#ifdef LINUXTHREADS_DETECT_UNSAFE_EXIT + /* Cancelled thread might have been in critical region unless terminated */ + if (th->p_terminated == 0) { + __pthread_exit_alone = 0; + __pthread_exit_code = 1; + } ++#endif kill(th->p_pid, __pthread_sig_cancel); } /* Now, wait for all these threads, so that they don't become zombies @@ -650,12 +659,14 @@ diff -ru ../../work/linuxthreads-2.2.3/pthread.c ./pthread.c __ATOMIC_INITIALIZER, /* struct pthread_atomic p_resume_count */ 0, /* char p_woken_by_cancel */ 0, /* char p_condvar_avail */ -@@ -185,6 +195,8 @@ +@@ -185,6 +195,10 @@ /* For process-wide exit() */ int __pthread_exit_requested; ++#ifdef LINUXTHREADS_DETECT_UNSAFE_EXIT +int __pthread_exit_requested_bymainthread = 0; +int __pthread_exit_alone = 1; ++#endif int __pthread_exit_code; /* Maximum stack size. */ @@ -816,10 +827,11 @@ diff -ru ../../work/linuxthreads-2.2.3/pthread.c ./pthread.c __libc_write(__pthread_manager_request, (char *) &request, sizeof(request)); suspend(self); -@@ -768,25 +759,30 @@ +@@ -768,25 +759,34 @@ if (self == __pthread_main_thread) { waitpid(__pthread_manager_thread.p_pid, NULL, __WCLONE); ++#ifdef LINUXTHREADS_DETECT_UNSAFE_EXIT + /* + * If other threads have been canceled then proper cleanup + * cannot be performed since a canceled thread might have @@ -828,9 +840,11 @@ diff -ru ../../work/linuxthreads-2.2.3/pthread.c ./pthread.c + */ + if (__pthread_exit_alone == 0) + _exit(1); ++#endif free (__pthread_manager_thread_bos); __pthread_manager_thread_bos = __pthread_manager_thread_tos = NULL; } ++#ifdef LINUXTHREADS_DETECT_UNSAFE_EXIT + /* + * If other threads have been canceled then proper cleanup + * cannot be performed since a canceled thread might have @@ -841,6 +855,7 @@ diff -ru ../../work/linuxthreads-2.2.3/pthread.c ./pthread.c + __pthread_exit_code = 1; + _exit(1); + } ++#endif } } @@ -860,13 +875,15 @@ diff -ru ../../work/linuxthreads-2.2.3/pthread.c ./pthread.c /* The handler for the RESTART signal just records the signal received in the thread descriptor, and optionally performs a siglongjmp -@@ -818,6 +812,9 @@ +@@ -818,6 +812,11 @@ if (__builtin_expect (__pthread_exit_requested, 0)) { /* Main thread should accumulate times for thread manager and its children, so that timings for main thread account for all threads. */ ++#ifdef LINUXTHREADS_DETECT_UNSAFE_EXIT + if (self == __pthread_main_thread && + __pthread_exit_requested_bymainthread != 0) + return; ++#endif if (self == __pthread_main_thread) waitpid(__pthread_manager_thread.p_pid, NULL, __WCLONE); _exit(__pthread_exit_code); |