This is the mail archive of the glibc-cvs@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

GNU C Library master sources branch, master, updated. glibc-2.15-871-g439bf40


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "GNU C Library master sources".

The branch, master has been updated
       via  439bf404b8fa125cf950dc1aa37838702c5353ea (commit)
      from  2949684c162a4413e42249d6b2ad554cb468b5be (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
http://sources.redhat.com/git/gitweb.cgi?p=glibc.git;a=commitdiff;h=439bf404b8fa125cf950dc1aa37838702c5353ea

commit 439bf404b8fa125cf950dc1aa37838702c5353ea
Author: Siddhesh Poyarekar <siddhesh@redhat.com>
Date:   Tue May 15 09:41:27 2012 +0530

    Allow a single-threaded program to cancel itself
    
    There is nothing in the POSIX specification to disallow a
    single-threaded program from cancelling itself, so we forcibly enable
    multiple_threads to allow the next available cancellation point in the
    thread to run.
    
    Also added additional tests to cover various cancellation scenarios.

diff --git a/NEWS b/NEWS
index 0e05fe4..e5a42d7 100644
--- a/NEWS
+++ b/NEWS
@@ -17,15 +17,16 @@ Version 2.16
   10153, 10210, 10254, 10346, 10545, 10716, 11174, 11322, 11365, 11451,
   11494, 11521, 11837, 11959, 12047, 12340, 13058, 13525, 13526, 13527,
   13528, 13529, 13530, 13531, 13532, 13533, 13547, 13551, 13552, 13553,
-  13555, 13559, 13563, 13566, 13583, 13592, 13618, 13637, 13656, 13658,
-  13673, 13691, 13695, 13704, 13705, 13706, 13726, 13738, 13739, 13750,
-  13758, 13760, 13761, 13775, 13786, 13787, 13792, 13806, 13824, 13840,
-  13841, 13844, 13846, 13851, 13852, 13854, 13871, 13872, 13873, 13879,
-  13883, 13884, 13885, 13886, 13892, 13895, 13908, 13910, 13911, 13912,
-  13913, 13914, 13915, 13916, 13917, 13918, 13919, 13920, 13921, 13922,
-  13923, 13924, 13926, 13927, 13928, 13938, 13941, 13942, 13954, 13955,
-  13956, 13963, 13967, 13970, 13973, 13979, 13983, 14012, 14027, 14033,
-  14034, 14040, 14049, 14053, 14055, 14064, 14080, 14083, 14103, 14104
+  13555, 13559, 13563, 13566, 13583, 13592, 13613, 13618, 13637, 13656,
+  13658, 13673, 13691, 13695, 13704, 13705, 13706, 13726, 13738, 13739,
+  13750, 13758, 13760, 13761, 13775, 13786, 13787, 13792, 13806, 13824,
+  13840, 13841, 13844, 13846, 13851, 13852, 13854, 13871, 13872, 13873,
+  13879, 13883, 13884, 13885, 13886, 13892, 13895, 13908, 13910, 13911,
+  13912, 13913, 13914, 13915, 13916, 13917, 13918, 13919, 13920, 13921,
+  13922, 13923, 13924, 13926, 13927, 13928, 13938, 13941, 13942, 13954,
+  13955, 13956, 13963, 13967, 13970, 13973, 13979, 13983, 14012, 14027,
+  14033, 14034, 14040, 14049, 14053, 14055, 14064, 14080, 14083, 14103,
+  14104
 
 * ISO C11 support:
 
diff --git a/nptl/ChangeLog b/nptl/ChangeLog
index cfc679c..bd7311f 100644
--- a/nptl/ChangeLog
+++ b/nptl/ChangeLog
@@ -1,3 +1,22 @@
+2012-05-15  Siddhesh Poyarekar  <siddhesh@redhat.com>
+	    Jakub Jelinek  <jakub@redhat.com>
+
+	[BZ #13613]
+	* Makefile (tests): Add test cases.
+	* descr.h (struct pthread): Add a comment describing multiple_threads.
+	* pthreadP.h (__pthread_multiple_threads): Expand comment to include
+	single-process case.
+	* pthread_cancel.c (pthread_cancel): Enable multiple_threads
+	before setting cancelstate of the thread.
+	* sysdeps/unix/sysv/linux/libc_multiple_threads.c
+	(__libc_multiple_threads): Add explanatory comment.
+	* tst-cancel-self-cancelstate.c: New test case.
+	* tst-cancel-self-canceltype.c: Likewise.
+	* tst-cancel-self-cleanup.c: Supporting file for test cases.
+	* tst-cancel-self-testcancel.c: New test case.
+	* tst-cancel-self.c: Likewise.
+	* vars.c: Expand comment to include single-process case.
+
 2012-05-14  H.J. Lu  <hongjiu.lu@intel.com>
 
 	* sysdeps/x86_64/tls.h: Don't include <bits/wordsize.h>.
diff --git a/nptl/Makefile b/nptl/Makefile
index 07a1022..2a36d01 100644
--- a/nptl/Makefile
+++ b/nptl/Makefile
@@ -236,6 +236,8 @@ tests = tst-typesizes \
 	tst-cancel11 tst-cancel12 tst-cancel13 tst-cancel14 tst-cancel15 \
 	tst-cancel16 tst-cancel17 tst-cancel18 tst-cancel19 tst-cancel20 \
 	tst-cancel21 tst-cancel22 tst-cancel23 tst-cancel24 tst-cancel25 \
+	tst-cancel-self tst-cancel-self-cancelstate \
+	tst-cancel-self-canceltype tst-cancel-self-testcancel \
 	tst-cleanup0 tst-cleanup1 tst-cleanup2 tst-cleanup3 tst-cleanup4 \
 	tst-flock1 tst-flock2 \
 	tst-signal1 tst-signal2 tst-signal3 tst-signal4 tst-signal5 \
diff --git a/nptl/descr.h b/nptl/descr.h
index c2fabeb..60d2d22 100644
--- a/nptl/descr.h
+++ b/nptl/descr.h
@@ -131,6 +131,21 @@ struct pthread
 #else
     struct
     {
+      /* multiple_threads is enabled either when the process has spawned at
+	 least one thread or when a single-threaded process cancels itself.
+	 This enables additional code to introduce locking before doing some
+	 compare_and_exchange operations and also enable cancellation points.
+	 The concepts of multiple threads and cancellation points ideally
+	 should be separate, since it is not necessary for multiple threads to
+	 have been created for cancellation points to be enabled, as is the
+	 case is when single-threaded process cancels itself.
+
+	 Since enabling multiple_threads enables additional code in
+	 cancellation points and compare_and_exchange operations, there is a
+	 potential for an unneeded performance hit when it is enabled in a
+	 single-threaded, self-canceling process.  This is OK though, since a
+	 single-threaded process will enable async cancellation only when it
+	 looks to cancel itself and is hence going to end anyway.  */
       int multiple_threads;
       int gscope_flag;
 # ifndef __ASSUME_PRIVATE_FUTEX
diff --git a/nptl/pthreadP.h b/nptl/pthreadP.h
index 68c690e..24a2471 100644
--- a/nptl/pthreadP.h
+++ b/nptl/pthreadP.h
@@ -378,7 +378,9 @@ extern int *__libc_pthread_init (unsigned long int *ptr,
 				 const struct pthread_functions *functions)
      internal_function;
 
-/* Variable set to a nonzero value if more than one thread runs or ran.  */
+/* Variable set to a nonzero value either if more than one thread runs or ran,
+   or if a single-threaded process is trying to cancel itself.  See
+   nptl/descr.h for more context on the single-threaded process case.  */
 extern int __pthread_multiple_threads attribute_hidden;
 /* Pointer to the corresponding variable in libc.  */
 extern int *__libc_multiple_threads_ptr attribute_hidden;
diff --git a/nptl/pthread_cancel.c b/nptl/pthread_cancel.c
index 249aa11..1bfca63 100644
--- a/nptl/pthread_cancel.c
+++ b/nptl/pthread_cancel.c
@@ -95,6 +95,14 @@ pthread_cancel (th)
 
 	  break;
 	}
+
+	/* A single-threaded process should be able to kill itself, since there is
+	   nothing in the POSIX specification that says that it cannot.  So we set
+	   multiple_threads to true so that cancellation points get executed.  */
+	THREAD_SETMEM (THREAD_SELF, header.multiple_threads, 1);
+#ifndef TLS_MULTIPLE_THREADS_IN_TCB
+	__pthread_multiple_threads = *__libc_multiple_threads_ptr = 1;
+#endif
     }
   /* Mark the thread as canceled.  This has to be done
      atomically since other bits could be modified as well.  */
diff --git a/nptl/sysdeps/unix/sysv/linux/libc_multiple_threads.c b/nptl/sysdeps/unix/sysv/linux/libc_multiple_threads.c
index 7fffb0d..459b8cf 100644
--- a/nptl/sysdeps/unix/sysv/linux/libc_multiple_threads.c
+++ b/nptl/sysdeps/unix/sysv/linux/libc_multiple_threads.c
@@ -20,6 +20,9 @@
 
 #ifndef NOT_IN_libc
 # ifndef TLS_MULTIPLE_THREADS_IN_TCB
+/* Variable set to a nonzero value either if more than one thread runs or ran,
+   or if a single-threaded process is trying to cancel itself.  See
+   nptl/descr.h for more context on the single-threaded process case.  */
 int __libc_multiple_threads attribute_hidden;
 # endif
 #endif
diff --git a/nptl/tst-cancel-self-cancelstate.c b/nptl/tst-cancel-self-cancelstate.c
new file mode 100644
index 0000000..c82e6f3
--- /dev/null
+++ b/nptl/tst-cancel-self-cancelstate.c
@@ -0,0 +1,65 @@
+/* Copyright (C) 2012 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, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <pthread.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include "tst-cancel-self-cleanup.c"
+
+
+static int
+do_test (void)
+{
+  int ret = 0;
+  volatile int should_fail = 1;
+
+  pthread_cleanup_push (cleanup, &should_fail);
+
+  if ((ret = pthread_setcancelstate (PTHREAD_CANCEL_DISABLE, NULL)) != 0)
+    {
+      printf ("setcancelstate(disable) failed: %s\n", strerror (ret));
+      exit (1);
+    }
+
+  if ((ret = pthread_cancel (pthread_self ())) != 0)
+    {
+      printf ("cancel failed: %s\n", strerror (ret));
+      exit (1);
+    }
+
+  usleep (100);
+  should_fail = 0;
+
+  if ((ret = pthread_setcancelstate (PTHREAD_CANCEL_ENABLE, NULL)) != 0)
+    {
+      printf ("setcancelstate(enable) failed: %s\n", strerror (ret));
+      exit (1);
+    }
+
+  /* The write syscall within this printf should give us our cancellation
+     point.  */
+  printf ("Could not cancel self.\n");
+  pthread_cleanup_pop (0);
+
+  return 1;
+}
+
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
diff --git a/nptl/vars.c b/nptl/tst-cancel-self-canceltype.c
similarity index 50%
copy from nptl/vars.c
copy to nptl/tst-cancel-self-canceltype.c
index 8f3023c..c9bb653 100644
--- a/nptl/vars.c
+++ b/nptl/tst-cancel-self-canceltype.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2012 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
@@ -15,28 +15,39 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <pthreadP.h>
+#include <pthread.h>
+#include <stdio.h>
 #include <stdlib.h>
-#include <tls.h>
+#include <string.h>
 #include <unistd.h>
+#include "tst-cancel-self-cleanup.c"
 
-/* Default stack size.  */
-size_t __default_stacksize attribute_hidden
-#ifdef SHARED
-;
-#else
-  = PTHREAD_STACK_MIN;
-#endif
-
-/* Flag whether the machine is SMP or not.  */
-int __is_smp attribute_hidden;
-
-#ifndef TLS_MULTIPLE_THREADS_IN_TCB
-/* Variable set to a nonzero value if more than one thread runs or ran.  */
-int __pthread_multiple_threads attribute_hidden;
-#endif
-
-/* Table of the key information.  */
-struct pthread_key_struct __pthread_keys[PTHREAD_KEYS_MAX]
-  __attribute__ ((nocommon));
-hidden_data_def (__pthread_keys)
+
+static int
+do_test (void)
+{
+  int ret = 0, should_fail = 0;
+
+  pthread_cleanup_push (cleanup, &should_fail);
+
+  if ((ret = pthread_setcanceltype (PTHREAD_CANCEL_ASYNCHRONOUS, NULL)) != 0)
+    {
+      printf ("setcanceltype failed: %s\n", strerror (ret));
+      exit (1);
+    }
+
+  if ((ret = pthread_cancel (pthread_self ())) != 0)
+    {
+      printf ("cancel failed: %s\n", strerror (ret));
+      exit (1);
+    }
+
+  /* Wait to be canceled. Don't give any cancellation points to play with.  */
+  while (1);
+  pthread_cleanup_pop (0);
+
+  return 1;
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
diff --git a/nptl/sysdeps/unix/sysv/linux/libc_multiple_threads.c b/nptl/tst-cancel-self-cleanup.c
similarity index 73%
copy from nptl/sysdeps/unix/sysv/linux/libc_multiple_threads.c
copy to nptl/tst-cancel-self-cleanup.c
index 7fffb0d..9b15f55 100644
--- a/nptl/sysdeps/unix/sysv/linux/libc_multiple_threads.c
+++ b/nptl/tst-cancel-self-cleanup.c
@@ -1,6 +1,5 @@
-/* Copyright (C) 2002, 2003 Free Software Foundation, Inc.
+/* Copyright (C) 2012 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
@@ -16,10 +15,9 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <pthreadP.h>
-
-#ifndef NOT_IN_libc
-# ifndef TLS_MULTIPLE_THREADS_IN_TCB
-int __libc_multiple_threads attribute_hidden;
-# endif
-#endif
+static void
+cleanup (void *cleanup_should_fail)
+{
+  printf ("Main thread got cancelled and is being cleaned up now\n");
+  exit (*(int *)cleanup_should_fail);
+}
diff --git a/nptl/vars.c b/nptl/tst-cancel-self-testcancel.c
similarity index 55%
copy from nptl/vars.c
copy to nptl/tst-cancel-self-testcancel.c
index 8f3023c..c942232 100644
--- a/nptl/vars.c
+++ b/nptl/tst-cancel-self-testcancel.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2012 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
@@ -15,28 +15,34 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <pthreadP.h>
+#include <pthread.h>
+#include <stdio.h>
 #include <stdlib.h>
-#include <tls.h>
+#include <string.h>
 #include <unistd.h>
+#include "tst-cancel-self-cleanup.c"
 
-/* Default stack size.  */
-size_t __default_stacksize attribute_hidden
-#ifdef SHARED
-;
-#else
-  = PTHREAD_STACK_MIN;
-#endif
-
-/* Flag whether the machine is SMP or not.  */
-int __is_smp attribute_hidden;
-
-#ifndef TLS_MULTIPLE_THREADS_IN_TCB
-/* Variable set to a nonzero value if more than one thread runs or ran.  */
-int __pthread_multiple_threads attribute_hidden;
-#endif
-
-/* Table of the key information.  */
-struct pthread_key_struct __pthread_keys[PTHREAD_KEYS_MAX]
-  __attribute__ ((nocommon));
-hidden_data_def (__pthread_keys)
+
+static int
+do_test (void)
+{
+  int ret = 0, should_fail = 0;
+
+  pthread_cleanup_push (cleanup, &should_fail);
+  if ((ret = pthread_cancel (pthread_self ())) != 0)
+    {
+      printf ("cancel failed: %s\n", strerror (ret));
+      exit (1);
+    }
+
+  pthread_testcancel ();
+
+  printf ("Could not cancel self.\n");
+  pthread_cleanup_pop (0);
+
+  return 1;
+}
+
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
diff --git a/nptl/vars.c b/nptl/tst-cancel-self.c
similarity index 55%
copy from nptl/vars.c
copy to nptl/tst-cancel-self.c
index 8f3023c..966698c 100644
--- a/nptl/vars.c
+++ b/nptl/tst-cancel-self.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 2004 Free Software Foundation, Inc.
+/* Copyright (C) 2012 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
@@ -15,28 +15,34 @@
    License along with the GNU C Library; if not, see
    <http://www.gnu.org/licenses/>.  */
 
-#include <pthreadP.h>
+#include <pthread.h>
+#include <stdio.h>
 #include <stdlib.h>
-#include <tls.h>
+#include <string.h>
 #include <unistd.h>
+#include "tst-cancel-self-cleanup.c"
 
-/* Default stack size.  */
-size_t __default_stacksize attribute_hidden
-#ifdef SHARED
-;
-#else
-  = PTHREAD_STACK_MIN;
-#endif
-
-/* Flag whether the machine is SMP or not.  */
-int __is_smp attribute_hidden;
-
-#ifndef TLS_MULTIPLE_THREADS_IN_TCB
-/* Variable set to a nonzero value if more than one thread runs or ran.  */
-int __pthread_multiple_threads attribute_hidden;
-#endif
-
-/* Table of the key information.  */
-struct pthread_key_struct __pthread_keys[PTHREAD_KEYS_MAX]
-  __attribute__ ((nocommon));
-hidden_data_def (__pthread_keys)
+
+static int
+do_test (void)
+{
+  int ret = 0, should_fail = 0;
+
+  pthread_cleanup_push (cleanup, &should_fail);
+  if ((ret = pthread_cancel (pthread_self ())) != 0)
+    {
+      printf ("cancel failed: %s\n", strerror (ret));
+      exit (1);
+    }
+
+  /* The write syscall within this printf should give us our cancellation
+     point.  */
+  printf ("Could not cancel self.\n");
+  pthread_cleanup_pop (0);
+
+  return 1;
+}
+
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
diff --git a/nptl/vars.c b/nptl/vars.c
index 8f3023c..43a6e39 100644
--- a/nptl/vars.c
+++ b/nptl/vars.c
@@ -32,7 +32,9 @@ size_t __default_stacksize attribute_hidden
 int __is_smp attribute_hidden;
 
 #ifndef TLS_MULTIPLE_THREADS_IN_TCB
-/* Variable set to a nonzero value if more than one thread runs or ran.  */
+/* Variable set to a nonzero value either if more than one thread runs or ran,
+   or if a single-threaded process is trying to cancel itself.  See
+   nptl/descr.h for more context on the single-threaded process case.  */
 int __pthread_multiple_threads attribute_hidden;
 #endif
 

-----------------------------------------------------------------------

Summary of changes:
 NEWS                                               |   19 +++---
 nptl/ChangeLog                                     |   19 ++++++
 nptl/Makefile                                      |    2 +
 nptl/descr.h                                       |   15 +++++
 nptl/pthreadP.h                                    |    4 +-
 nptl/pthread_cancel.c                              |    8 +++
 .../unix/sysv/linux/libc_multiple_threads.c        |    3 +
 nptl/tst-cancel-self-cancelstate.c                 |   65 ++++++++++++++++++++
 nptl/tst-cancel-self-canceltype.c                  |   53 ++++++++++++++++
 nptl/tst-cancel-self-cleanup.c                     |   23 +++++++
 nptl/tst-cancel-self-testcancel.c                  |   48 ++++++++++++++
 nptl/tst-cancel-self.c                             |   48 ++++++++++++++
 nptl/vars.c                                        |    4 +-
 13 files changed, 300 insertions(+), 11 deletions(-)
 create mode 100644 nptl/tst-cancel-self-cancelstate.c
 create mode 100644 nptl/tst-cancel-self-canceltype.c
 create mode 100644 nptl/tst-cancel-self-cleanup.c
 create mode 100644 nptl/tst-cancel-self-testcancel.c
 create mode 100644 nptl/tst-cancel-self.c


hooks/post-receive
-- 
GNU C Library master sources


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]