From 5cba613e21b7b704bcfd1340081c4b5a1b21ad4c Mon Sep 17 00:00:00 2001
From: bryce <bryce@138bc75d-0d04-0410-961f-82ee72b054a4>
Date: Sat, 30 Dec 2000 12:18:39 +0000
Subject: [PATCH] For boehm-gc: 	* configure.in: Rename THREADLIB to
 THREADLIBS. 	* Makefile.am (LINK): Add $(THREADLIBS) to libtool command
 line. This 	ensures that we link the correct version of the linuxthreads
 semaphore 	functions. 	* Makefile.in: Rebuilt. 	* configure:
 Rebuilt.

	* linux_thread.c (GC_thr_init, GC_suspend_handler): Add SIGABRT to the
	list of signals which are not blocked during suspend in the NO_SIGNALS
	case.

For libjava:
	* Makefile.am (libgcj_la_LIBADD): Add $(THREADLIBS). This ensures that
	the correct versions of various linuxthreads functions get linked.
	* Makefile.in: Rebuilt.
	* java/lang/natThread.cc (finalize_native): New static function. Call
	_Jv_ThreadDestroyData.
	(initialize_native): Register finalizer for "data".
	* include/posix-threads.h (_Jv_ThreadInitData): New simpler prototype.
	(_Jv_ThreadDestroyData): New prototype.
	* include/win32-threads.h: Ditto.
	* include/no-threads.h: Ditto.
	* posix-threads.cc (_Jv_ThreadInitData): Implement new prototype.
	(_Jv_ThreadDestroyData): New function. Free native thread "data" and
	move mutex and condition variable destroy code from:
	(really_start): ...here.
	(_Jv_ThreadStart): Set PTHREAD_CREATE_DETACHED.
	* win32-threads.cc (_Jv_ThreadInitData): Implement new prototype.
	(_Jv_ThreadDestroyData): Implemented.
	* nogc.cc (_Jv_AllocObject): Use "void *" not "ptr_t".
	(_Jv_AllocArray): Ditto.


git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@38557 138bc75d-0d04-0410-961f-82ee72b054a4
---
 boehm-gc/ChangeLog              | 13 ++++++
 boehm-gc/Makefile.am            |  7 ++-
 boehm-gc/Makefile.in            | 75 +++++++++++++++++++++++++++------
 boehm-gc/configure              |  6 +--
 boehm-gc/configure.in           |  6 +--
 boehm-gc/linux_threads.c        |  4 +-
 libjava/ChangeLog               | 22 ++++++++++
 libjava/include/no-threads.h    |  9 +++-
 libjava/include/posix-threads.h |  3 +-
 libjava/include/win32-threads.h |  3 +-
 libjava/java/lang/natThread.cc  | 25 ++++++++---
 libjava/nogc.cc                 |  6 +--
 libjava/posix-threads.cc        | 34 +++++++--------
 libjava/win32-threads.cc        | 17 +++++---
 14 files changed, 171 insertions(+), 59 deletions(-)

diff --git a/boehm-gc/ChangeLog b/boehm-gc/ChangeLog
index eb91029ea62d..2ae9240ed323 100644
--- a/boehm-gc/ChangeLog
+++ b/boehm-gc/ChangeLog
@@ -1,3 +1,16 @@
+2000-12-30  Bryce McKinlay  <bryce@albatross.co.nz>
+
+	* configure.in: Rename THREADLIB to THREADLIBS.
+	* Makefile.am (LINK): Add $(THREADLIBS) to libtool command line. This
+	ensures that we link the correct version of the linuxthreads semaphore
+	functions.
+	* Makefile.in: Rebuilt.
+	* configure: Rebuilt.
+	
+	* linux_thread.c (GC_thr_init, GC_suspend_handler): Add SIGABRT to the 
+	list of signals which are not blocked during suspend in the NO_SIGNALS
+	case.
+
 2000-12-23  Hans Boehm  <Hans_Boehm@hp.com>
 
 	* gcj_mlc.c (GC_gcj_malloc): Don't release allocation lock twice.
diff --git a/boehm-gc/Makefile.am b/boehm-gc/Makefile.am
index f2286c4b2e98..06d740b15af8 100644
--- a/boehm-gc/Makefile.am
+++ b/boehm-gc/Makefile.am
@@ -32,7 +32,10 @@ hpux_irix_threads.c linux_threads.c malloc.c mallocx.c mark.c mark_rts.c \
 misc.c new_hblk.c obj_map.c os_dep.c pcr_interface.c ptr_chck.c	\
 real_malloc.c reclaim.c solaris_pthreads.c solaris_threads.c \
 solaris_threads.h stubborn.c typd_mlc.c version.h weakpointer.h
-libgcjgc_la_LIBADD = @addobjs@
+
+# Include THREADLIBS here to ensure that the correct versions of
+# linuxthread semaphore functions get linked:
+libgcjgc_la_LIBADD = @addobjs@ $(THREADLIBS)
 libgcjgc_la_DEPENDENCIES = @addobjs@
 libgcjgc_la_LDFLAGS = -version-info 1:1:0 -rpath $(toolexeclibdir)
 
@@ -45,7 +48,7 @@ AM_CFLAGS = @BOEHM_GC_CFLAGS@
 
 check_PROGRAMS = gctest
 gctest_SOURCES = test.c
-gctest_LDADD = ./libgcjgc.la $(THREADLIB) $(EXTRA_TEST_LIBS)
+gctest_LDADD = ./libgcjgc.la $(THREADLIBS) $(EXTRA_TEST_LIBS)
 
 TESTS = gctest
 
diff --git a/boehm-gc/Makefile.in b/boehm-gc/Makefile.in
index e12d68d709ee..ec91baa62df2 100644
--- a/boehm-gc/Makefile.in
+++ b/boehm-gc/Makefile.in
@@ -87,7 +87,7 @@ OBJEXT = @OBJEXT@
 PACKAGE = @PACKAGE@
 RANLIB = @RANLIB@
 STRIP = @STRIP@
-THREADLIB = @THREADLIB@
+THREADLIBS = @THREADLIBS@
 VERSION = @VERSION@
 addobjs = @addobjs@
 boehm_gc_basedir = @boehm_gc_basedir@
@@ -102,19 +102,30 @@ MULTIDIRS =
 MULTISUBDIR = 
 MULTIDO = true
 MULTICLEAN = true
-@USE_LIBDIR_TRUE@toolexeclibdir = $(libdir)$(MULTISUBDIR)
-@USE_LIBDIR_FALSE@toolexeclibdir = $(toolexecdir)/lib$(MULTISUBDIR)
-@USE_LIBDIR_FALSE@toolexecdir = $(exec_prefix)/$(target_alias)
+@USE_LIBDIR_TRUE@toolexeclibdir = @USE_LIBDIR_TRUE@$(libdir)$(MULTISUBDIR)
+@USE_LIBDIR_FALSE@toolexeclibdir = @USE_LIBDIR_FALSE@$(toolexecdir)/lib$(MULTISUBDIR)
+@USE_LIBDIR_FALSE@toolexecdir = @USE_LIBDIR_FALSE@$(exec_prefix)/$(target_alias)
 
 toolexeclib_LTLIBRARIES = $(target_all)
 EXTRA_LTLIBRARIES = libgcjgc.la
-libgcjgc_la_SOURCES = allchblk.c alloc.c blacklst.c checksums.c	gcconfig.h dbg_mlc.c dyn_load.c finalize.c gc.h gc_alloc.h gc_cpp.h gc_hdrs.h gc_mark.h gc_priv.h gc_private.h gc_typed.h gcj_mlc.c headers.c hpux_irix_threads.c linux_threads.c malloc.c mallocx.c mark.c mark_rts.c misc.c new_hblk.c obj_map.c os_dep.c pcr_interface.c ptr_chck.c	real_malloc.c reclaim.c solaris_pthreads.c solaris_threads.c solaris_threads.h stubborn.c typd_mlc.c version.h weakpointer.h
-
-libgcjgc_la_LIBADD = @addobjs@
+libgcjgc_la_SOURCES = allchblk.c alloc.c blacklst.c checksums.c	\
+gcconfig.h dbg_mlc.c dyn_load.c finalize.c gc.h gc_alloc.h gc_cpp.h \
+gc_hdrs.h gc_mark.h gc_priv.h gc_private.h gc_typed.h gcj_mlc.c headers.c \
+hpux_irix_threads.c linux_threads.c malloc.c mallocx.c mark.c mark_rts.c \
+misc.c new_hblk.c obj_map.c os_dep.c pcr_interface.c ptr_chck.c	\
+real_malloc.c reclaim.c solaris_pthreads.c solaris_threads.c \
+solaris_threads.h stubborn.c typd_mlc.c version.h weakpointer.h
+
+
+# Include THREADLIBS here to ensure that the correct versions of
+# linuxthread semaphore functions get linked:
+libgcjgc_la_LIBADD = @addobjs@ $(THREADLIBS)
 libgcjgc_la_DEPENDENCIES = @addobjs@
 libgcjgc_la_LDFLAGS = -version-info 1:1:0 -rpath $(toolexeclibdir)
 
-EXTRA_libgcjgc_la_SOURCES = alpha_mach_dep.s mips_sgi_mach_dep.s mips_ultrix_mach_dep.s rs6000_mach_dep.s sparc_mach_dep.s sparc_sunos4_mach_dep.s mach_dep.c ecos.cc
+EXTRA_libgcjgc_la_SOURCES = alpha_mach_dep.s mips_sgi_mach_dep.s \
+mips_ultrix_mach_dep.s rs6000_mach_dep.s sparc_mach_dep.s \
+sparc_sunos4_mach_dep.s mach_dep.c ecos.cc
 
 
 AM_CXXFLAGS = @BOEHM_GC_CFLAGS@
@@ -123,20 +134,58 @@ AM_CFLAGS = @BOEHM_GC_CFLAGS@
 
 check_PROGRAMS = gctest
 gctest_SOURCES = test.c
-gctest_LDADD = ./libgcjgc.la $(THREADLIB) $(EXTRA_TEST_LIBS)
+gctest_LDADD = ./libgcjgc.la $(THREADLIBS) $(EXTRA_TEST_LIBS)
 
 TESTS = gctest
 
 all_objs = @addobjs@ $(libgcjgc_la_OBJECTS)
 
-LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) 	$(AM_CPPFLAGS) $(CPPFLAGS) 	$(AM_CFLAGS) $(MY_CFLAGS) $(BOEHM_GC_CFLAGS) 
+LTCOMPILE = $(LIBTOOL) --mode=compile $(CC) $(DEFS) $(INCLUDES) \
+	$(AM_CPPFLAGS) $(CPPFLAGS) \
+	$(AM_CFLAGS) $(MY_CFLAGS) $(BOEHM_GC_CFLAGS) 
 
 LINK = $(LIBTOOL) --mode=link $(CC) $(AM_CFLAGS) $(MY_CFLAGS) $(LDFLAGS) -o $@
 
 # Work around what appears to be a GNU make bug handling MAKEFLAGS
 # values defined in terms of make variables, as is the case for CC and
 # friends when we are called from the top level Makefile.
-AM_MAKEFLAGS =  	"AR_FLAGS=$(AR_FLAGS)" 	"CC_FOR_BUILD=$(CC_FOR_BUILD)" 	"CFLAGS=$(CFLAGS)" 	"CXXFLAGS=$(CXXFLAGS)" 	"CFLAGS_FOR_BUILD=$(CFLAGS_FOR_BUILD)" 	"CFLAGS_FOR_TARGET=$(CFLAGS_FOR_TARGET)" 	"INSTALL=$(INSTALL)" 	"INSTALL_DATA=$(INSTALL_DATA)" 	"INSTALL_PROGRAM=$(INSTALL_PROGRAM)" 	"INSTALL_SCRIPT=$(INSTALL_SCRIPT)" 	"LDFLAGS=$(LDFLAGS)" 	"LIBCFLAGS=$(LIBCFLAGS)" 	"LIBCFLAGS_FOR_TARGET=$(LIBCFLAGS_FOR_TARGET)" 	"MAKE=$(MAKE)" 	"MAKEINFO=$(MAKEINFO) $(MAKEINFOFLAGS)" 	"PICFLAG=$(PICFLAG)" 	"PICFLAG_FOR_TARGET=$(PICFLAG_FOR_TARGET)" 	"SHELL=$(SHELL)" 	"EXPECT=$(EXPECT)" 	"RUNTEST=$(RUNTEST)" 	"RUNTESTFLAGS=$(RUNTESTFLAGS)" 	"exec_prefix=$(exec_prefix)" 	"infodir=$(infodir)" 	"libdir=$(libdir)" 	"prefix=$(prefix)" 	"tooldir=$(tooldir)" 	"AR=$(AR)" 	"AS=$(AS)" 	"CC=$(CC)" 	"CXX=$(CXX)" 	"LD=$(LD)" 	"LIBCFLAGS=$(LIBCFLAGS)" 	"NM=$(NM)" 	"PICFLAG=$(PICFLAG)" 	"RANLIB=$(RANLIB)" 	"DESTDIR=$(DESTDIR)"
+AM_MAKEFLAGS = \
+	"AR_FLAGS=$(AR_FLAGS)" \
+	"CC_FOR_BUILD=$(CC_FOR_BUILD)" \
+	"CFLAGS=$(CFLAGS)" \
+	"CXXFLAGS=$(CXXFLAGS)" \
+	"CFLAGS_FOR_BUILD=$(CFLAGS_FOR_BUILD)" \
+	"CFLAGS_FOR_TARGET=$(CFLAGS_FOR_TARGET)" \
+	"INSTALL=$(INSTALL)" \
+	"INSTALL_DATA=$(INSTALL_DATA)" \
+	"INSTALL_PROGRAM=$(INSTALL_PROGRAM)" \
+	"INSTALL_SCRIPT=$(INSTALL_SCRIPT)" \
+	"LDFLAGS=$(LDFLAGS)" \
+	"LIBCFLAGS=$(LIBCFLAGS)" \
+	"LIBCFLAGS_FOR_TARGET=$(LIBCFLAGS_FOR_TARGET)" \
+	"MAKE=$(MAKE)" \
+	"MAKEINFO=$(MAKEINFO) $(MAKEINFOFLAGS)" \
+	"PICFLAG=$(PICFLAG)" \
+	"PICFLAG_FOR_TARGET=$(PICFLAG_FOR_TARGET)" \
+	"SHELL=$(SHELL)" \
+	"EXPECT=$(EXPECT)" \
+	"RUNTEST=$(RUNTEST)" \
+	"RUNTESTFLAGS=$(RUNTESTFLAGS)" \
+	"exec_prefix=$(exec_prefix)" \
+	"infodir=$(infodir)" \
+	"libdir=$(libdir)" \
+	"prefix=$(prefix)" \
+	"tooldir=$(tooldir)" \
+	"AR=$(AR)" \
+	"AS=$(AS)" \
+	"CC=$(CC)" \
+	"CXX=$(CXX)" \
+	"LD=$(LD)" \
+	"LIBCFLAGS=$(LIBCFLAGS)" \
+	"NM=$(NM)" \
+	"PICFLAG=$(PICFLAG)" \
+	"RANLIB=$(RANLIB)" \
+	"DESTDIR=$(DESTDIR)"
 
 
 CONFIG_STATUS_DEPENDENCIES = $(boehm_gc_basedir)/configure.host
@@ -176,7 +225,7 @@ aclocal.m4 configure configure.in
 
 DISTFILES = $(DIST_COMMON) $(SOURCES) $(HEADERS) $(TEXINFOS) $(EXTRA_DIST)
 
-TAR = gtar
+TAR = tar
 GZIP_ENV = --best
 SOURCES = $(libgcjgc_la_SOURCES) $(EXTRA_libgcjgc_la_SOURCES) $(gctest_SOURCES)
 OBJECTS = $(libgcjgc_la_OBJECTS) $(gctest_OBJECTS)
@@ -357,7 +406,7 @@ distdir: $(DISTFILES)
 	@for file in $(DISTFILES); do \
 	  if test -f $$file; then d=.; else d=$(srcdir); fi; \
 	  if test -d $$d/$$file; then \
-	    cp -pr $$/$$file $(distdir)/$$file; \
+	    cp -pr $$d/$$file $(distdir)/$$file; \
 	  else \
 	    test -f $(distdir)/$$file \
 	    || ln $$d/$$file $(distdir)/$$file 2> /dev/null \
diff --git a/boehm-gc/configure b/boehm-gc/configure
index cd68c6b51e3d..c11cf55f7f13 100755
--- a/boehm-gc/configure
+++ b/boehm-gc/configure
@@ -2609,7 +2609,7 @@ if test "$THREADS" = yes; then
 fi
 
 INCLUDES=
-THREADLIB=
+THREADLIBS=
 case "$THREADS" in
  no | none | single)
     THREADS=none
@@ -2644,7 +2644,7 @@ EOF
 
 	;;
     esac
-    THREADLIB=-lpthread
+    THREADLIBS=-lpthread
     ;;
  decosf1 | irix | mach | os2 | solaris | win32 | dce | vxworks)
     { echo "configure: error: thread package $THREADS not yet supported" 1>&2; exit 1; }
@@ -3042,7 +3042,7 @@ s%@OBJEXT@%$OBJEXT%g
 s%@STRIP@%$STRIP%g
 s%@LIBTOOL@%$LIBTOOL%g
 s%@CXXCPP@%$CXXCPP%g
-s%@THREADLIB@%$THREADLIB%g
+s%@THREADLIBS@%$THREADLIBS%g
 s%@EXTRA_TEST_LIBS@%$EXTRA_TEST_LIBS%g
 s%@target_all@%$target_all%g
 s%@INCLUDES@%$INCLUDES%g
diff --git a/boehm-gc/configure.in b/boehm-gc/configure.in
index ea23b5123e5a..6a75b192b703 100644
--- a/boehm-gc/configure.in
+++ b/boehm-gc/configure.in
@@ -66,7 +66,7 @@ if test "$THREADS" = yes; then
 fi
 
 INCLUDES=
-THREADLIB=
+THREADLIBS=
 case "$THREADS" in
  no | none | single)
     THREADS=none
@@ -86,7 +86,7 @@ case "$THREADS" in
 	AC_DEFINE(IRIX_THREADS)
 	;;
     esac
-    THREADLIB=-lpthread
+    THREADLIBS=-lpthread
     ;;
  decosf1 | irix | mach | os2 | solaris | win32 | dce | vxworks)
     AC_MSG_ERROR(thread package $THREADS not yet supported)
@@ -96,7 +96,7 @@ case "$THREADS" in
     ;;
 esac
 AC_MSG_RESULT($THREADS)
-AC_SUBST(THREADLIB)
+AC_SUBST(THREADLIBS)
 
 AC_CHECK_LIB(dl, dlopen, EXTRA_TEST_LIBS="$EXTRA_TEST_LIBS -ldl")
 AC_SUBST(EXTRA_TEST_LIBS)
diff --git a/boehm-gc/linux_threads.c b/boehm-gc/linux_threads.c
index c3f19b8ec577..cac52374d723 100644
--- a/boehm-gc/linux_threads.c
+++ b/boehm-gc/linux_threads.c
@@ -201,6 +201,7 @@ void GC_suspend_handler(int sig)
       if (sigdelset(&mask, SIGINT) != 0) ABORT("sigdelset() failed");
       if (sigdelset(&mask, SIGQUIT) != 0) ABORT("sigdelset() failed");
       if (sigdelset(&mask, SIGTERM) != 0) ABORT("sigdelset() failed");
+      if (sigdelset(&mask, SIGABRT) != 0) ABORT("sigdelset() failed");
 #   endif
     do {
 	    me->signal = 0;
@@ -487,7 +488,8 @@ void GC_thr_init()
 #   ifdef NO_SIGNALS
       if (sigdelset(&act.sa_mask, SIGINT) != 0
 	  || sigdelset(&act.sa_mask, SIGQUIT != 0)
-	  || sigdelset(&act.sa_mask, SIGTERM != 0)) {
+	  || sigdelset(&act.sa_mask, SIGTERM != 0)
+	  || sigdelset(&act.sa_mask, SIGABRT != 0)) {
         ABORT("sigdelset() failed");
       }
 #   endif
diff --git a/libjava/ChangeLog b/libjava/ChangeLog
index 2dcc45d33f33..551c2e68c327 100644
--- a/libjava/ChangeLog
+++ b/libjava/ChangeLog
@@ -1,3 +1,25 @@
+2000-12-30  Bryce McKinlay  <bryce@albatross.co.nz>
+
+	* Makefile.am (libgcj_la_LIBADD): Add $(THREADLIBS). This ensures that
+	the correct versions of various linuxthreads functions get linked.
+	* Makefile.in: Rebuilt.
+	* java/lang/natThread.cc (finalize_native): New static function. Call
+	_Jv_ThreadDestroyData.
+	(initialize_native): Register finalizer for "data".
+	* include/posix-threads.h (_Jv_ThreadInitData): New simpler prototype.
+	(_Jv_ThreadDestroyData): New prototype.
+	* include/win32-threads.h: Ditto.
+	* include/no-threads.h: Ditto.
+	* posix-threads.cc (_Jv_ThreadInitData): Implement new prototype.
+	(_Jv_ThreadDestroyData): New function. Free native thread "data" and 
+	move mutex and condition variable destroy code from:
+	(really_start): ...here.
+	(_Jv_ThreadStart): Set PTHREAD_CREATE_DETACHED.
+	* win32-threads.cc (_Jv_ThreadInitData): Implement new prototype.
+	(_Jv_ThreadDestroyData): Implemented.
+	* nogc.cc (_Jv_AllocObject): Use "void *" not "ptr_t".
+	(_Jv_AllocArray): Ditto.	
+	
 2000-12-27  Jeff Sturm  <jeff.sturm@commerceone.com>
 
 	* java/sql/DriverManager.java (getConnection): Don't set user/password
diff --git a/libjava/include/no-threads.h b/libjava/include/no-threads.h
index e500184ca674..69b6d437ba1a 100644
--- a/libjava/include/no-threads.h
+++ b/libjava/include/no-threads.h
@@ -102,10 +102,15 @@ _Jv_InitThreads (void)
 {
 }
 
+inline _Jv_Thread_t *
+_Jv_ThreadInitData (java::lang::Thread *)
+{
+  return NULL;
+}
+
 inline void
-_Jv_ThreadInitData (_Jv_Thread_t **data, java::lang::Thread *)
+_Jv_ThreadDestroyData (_Jv_Thread_t *data)
 {
-  *data = NULL;
 }
 
 inline java::lang::Thread *
diff --git a/libjava/include/posix-threads.h b/libjava/include/posix-threads.h
index 5b1f075dc0dd..75285ca6f50a 100644
--- a/libjava/include/posix-threads.h
+++ b/libjava/include/posix-threads.h
@@ -169,7 +169,8 @@ _Jv_MutexDestroy (_Jv_Mutex_t *mu)
 
 void _Jv_InitThreads (void);
 
-void _Jv_ThreadInitData (_Jv_Thread_t **data, java::lang::Thread *thread);
+_Jv_Thread_t *_Jv_ThreadInitData (java::lang::Thread *thread);
+void _Jv_ThreadDestroyData (_Jv_Thread_t *data);
 
 inline java::lang::Thread *
 _Jv_ThreadCurrent (void)
diff --git a/libjava/include/win32-threads.h b/libjava/include/win32-threads.h
index 4938d5faf57a..31b961b253b8 100644
--- a/libjava/include/win32-threads.h
+++ b/libjava/include/win32-threads.h
@@ -97,7 +97,8 @@ _Jv_MutexUnlock (_Jv_Mutex_t *mu)
 //
 
 void _Jv_InitThreads (void);
-void _Jv_ThreadInitData (_Jv_Thread_t **data, java::lang::Thread *thread);
+_Jv_Thread_t *_Jv_ThreadInitData (java::lang::Thread *thread);
+void _Jv_ThreadDestroyData (_Jv_Thread_t *data);
 
 inline java::lang::Thread *
 _Jv_ThreadCurrent (void)
diff --git a/libjava/java/lang/natThread.cc b/libjava/java/lang/natThread.cc
index 2b9afb53dec2..796713af4009 100644
--- a/libjava/java/lang/natThread.cc
+++ b/libjava/java/lang/natThread.cc
@@ -50,26 +50,39 @@ struct natThread
   JNIEnv *jni_env;
 };
 
+static void finalize_native (jobject ptr);
+
 // This is called from the constructor to initialize the native side
 // of the Thread.
 void
 java::lang::Thread::initialize_native (void)
 {
-  // FIXME: this must interact with the GC in some logical way.  At
-  // the very least we must register a finalizer to clean up.  This
-  // isn't easy to do.  If the Thread object resurrects itself in its
-  // own finalizer then we will need to reinitialize this structure at
-  // any "interesting" point.
   natThread *nt = (natThread *) _Jv_AllocBytes (sizeof (natThread));
+  
+  // The native thread data is kept in a Object field, not a rawdata, so that
+  // the GC allocator can be used and a finalizer run after the thread becomes
+  // unreachable. Note that this relies on the GC's ability to finalize 
+  // non-Java objects. FIXME?
   data = reinterpret_cast<jobject> (nt);
+  
+  // Register a finalizer to clean up the native thread resources.
+  _Jv_RegisterFinalizer (data, finalize_native);
+
   _Jv_MutexInit (&nt->join_mutex);
   _Jv_CondInit (&nt->join_cond);
-  _Jv_ThreadInitData (&nt->thread, this);
+  nt->thread = _Jv_ThreadInitData (this);
   // FIXME: if JNI_ENV is set we will want to free it.  It is
   // malloc()d.
   nt->jni_env = NULL;
 }
 
+static void
+finalize_native (jobject ptr)
+{
+  natThread *nt = (natThread *) ptr;
+  _Jv_ThreadDestroyData (nt->thread);
+}
+
 jint
 java::lang::Thread::countStackFrames (void)
 {
diff --git a/libjava/nogc.cc b/libjava/nogc.cc
index b5bd6f3d1f56..08296719cbfa 100644
--- a/libjava/nogc.cc
+++ b/libjava/nogc.cc
@@ -1,4 +1,4 @@
-// nogc.cc - Code to implement no GC.
+// nogc.cc - Implement null garbage collector.
 
 /* Copyright (C) 1998, 1999, 2000  Free Software Foundation
 
@@ -31,7 +31,7 @@ void *
 _Jv_AllocObj (jsize size, jclass klass)
 {
   total += size;
-  ptr_t obj = calloc (size, 1);
+  void *obj = calloc (size, 1);
   *((_Jv_VTable **) obj) = klass->vtable;
   return obj;
 }
@@ -40,7 +40,7 @@ void *
 _Jv_AllocArray (jsize size, jclass klass)
 {
   total += size;
-  ptr_t obj = calloc (size, 1);
+  void *obj = calloc (size, 1);
   *((_Jv_VTable **) obj) = klass->vtable;
   return obj;
 }
diff --git a/libjava/posix-threads.cc b/libjava/posix-threads.cc
index 2c7babb97a08..20538436481c 100644
--- a/libjava/posix-threads.cc
+++ b/libjava/posix-threads.cc
@@ -147,7 +147,7 @@ _Jv_CondWait (_Jv_ConditionVariable_t *cv, _Jv_Mutex_t *mu,
       else
 	r = pthread_cond_timedwait (&current->wait_cond, &current->wait_mutex, 
 				    &ts);
-				    
+
       // In older glibc's (prior to 2.1.3), the cond_wait functions may 
       // spuriously wake up on a signal. Catch that here.
       if (r != EINTR)
@@ -297,20 +297,25 @@ _Jv_InitThreads (void)
   sigaction (INTR, &act, NULL);
 }
 
-void
-_Jv_ThreadInitData (_Jv_Thread_t **data, java::lang::Thread *obj)
+_Jv_Thread_t *
+_Jv_ThreadInitData (java::lang::Thread *obj)
 {
-  _Jv_Thread_t *info = new _Jv_Thread_t;
-  info->flags = 0;
-  info->thread_obj = obj;
+  _Jv_Thread_t *data = new _Jv_Thread_t;
+  data->flags = 0;
+  data->thread_obj = obj;
 
-  pthread_mutex_init (&info->wait_mutex, NULL);
-  pthread_cond_init (&info->wait_cond, NULL);
+  pthread_mutex_init (&data->wait_mutex, NULL);
+  pthread_cond_init (&data->wait_cond, NULL);
 
-  // FIXME register a finalizer for INFO here.
-  // FIXME also must mark INFO somehow.
+  return data;
+}
 
-  *data = info;
+void
+_Jv_ThreadDestroyData (_Jv_Thread_t *data)
+{
+  pthread_mutex_destroy (&data->wait_mutex);
+  pthread_cond_destroy (&data->wait_cond);
+  delete data;
 }
 
 void
@@ -352,12 +357,6 @@ really_start (void *x)
       pthread_mutex_unlock (&daemon_mutex);
     }
   
-#ifndef LINUX_THREADS
-  // Clean up. These calls do nothing on Linux.
-  pthread_mutex_destroy (&info->data->wait_mutex);
-  pthread_cond_destroy (&info->data->wait_cond);
-#endif /* ! LINUX_THREADS */
-
   return NULL;
 }
 
@@ -377,6 +376,7 @@ _Jv_ThreadStart (java::lang::Thread *thread, _Jv_Thread_t *data,
 
   pthread_attr_init (&attr);
   pthread_attr_setschedparam (&attr, &param);
+  pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED);
 
   // FIXME: handle marking the info object for GC.
   info = (struct starter *) _Jv_AllocBytes (sizeof (struct starter));
diff --git a/libjava/win32-threads.cc b/libjava/win32-threads.cc
index 8da274f1a34f..29b6a72a8fcb 100644
--- a/libjava/win32-threads.cc
+++ b/libjava/win32-threads.cc
@@ -123,16 +123,19 @@ _Jv_InitThreads (void)
   non_daemon_count = 0;
 }
 
-void
-_Jv_ThreadInitData (_Jv_Thread_t **data, java::lang::Thread *)
+_Jv_Thread_t *
+_Jv_ThreadInitData (java::lang::Thread *)
 {
-  _Jv_Thread_t *info = new _Jv_Thread_t;
-  info->flags = 0;
+  _Jv_Thread_t *data = new _Jv_Thread_t;
+  data->flags = 0;
 
-  // FIXME register a finalizer for INFO here.
-  // FIXME also must mark INFO somehow.
+  return data;
+}
 
-  *data = info;
+void
+_Jv_ThreadDestroyData (_Jv_Thread_t *data)
+{
+  delete data;
 }
 
 void
-- 
GitLab