View | Details | Raw Unified | Return to bug 18435 | Differences between
and this patch

Collapse All | Expand All

(-)a/ChangeLog (+10 lines)
Lines 1-3 Link Here
1
2015-05-19  Martin Sebor  <msebor@redhat.com>
2
3
	[BZ #18???]
4
	* nptl/ptherad_once (CleanupInfo): New struct.
5
	(clear_once_control): Replace...
6
	(cleanup_maybe_clear_once_control): ...with this.
7
	(__pthread_once_slow): Replace calls to pthread_cleanup_push and
8
	pthread_cleanup_pop with a cleanup object of struct CleanupInfo.
9
	* nptl/tst-once5.cc: New test.
10
1
2015-05-18  Siddhesh Poyarekar  <siddhesh@redhat.com>
11
2015-05-18  Siddhesh Poyarekar  <siddhesh@redhat.com>
2
12
3
	* .gitignore: Ignore generated *.pyc.
13
	* .gitignore: Ignore generated *.pyc.
(-)a/nptl/Makefile (-1 / +2 lines)
Lines 203-208 CFLAGS-send.c = -fexceptions -fasynchronous-unwind-tables Link Here
203
203
204
CFLAGS-pt-system.c = -fexceptions
204
CFLAGS-pt-system.c = -fexceptions
205
205
206
LDFLAGS-tst-once5 = -lstdc++
206
207
207
tests = tst-typesizes \
208
tests = tst-typesizes \
208
	tst-attr1 tst-attr2 tst-attr3 tst-default-attr \
209
	tst-attr1 tst-attr2 tst-attr3 tst-default-attr \
Lines 224-230 tests = tst-typesizes \ Link Here
224
	tst-rwlock1 tst-rwlock2 tst-rwlock2a tst-rwlock3 tst-rwlock4 \
225
	tst-rwlock1 tst-rwlock2 tst-rwlock2a tst-rwlock3 tst-rwlock4 \
225
	tst-rwlock5 tst-rwlock6 tst-rwlock7 tst-rwlock8 tst-rwlock9 \
226
	tst-rwlock5 tst-rwlock6 tst-rwlock7 tst-rwlock8 tst-rwlock9 \
226
	tst-rwlock10 tst-rwlock11 tst-rwlock12 tst-rwlock13 tst-rwlock14 \
227
	tst-rwlock10 tst-rwlock11 tst-rwlock12 tst-rwlock13 tst-rwlock14 \
227
	tst-once1 tst-once2 tst-once3 tst-once4 \
228
	tst-once1 tst-once2 tst-once3 tst-once4 tst-once5 \
228
	tst-key1 tst-key2 tst-key3 tst-key4 \
229
	tst-key1 tst-key2 tst-key3 tst-key4 \
229
	tst-sem1 tst-sem2 tst-sem3 tst-sem4 tst-sem5 tst-sem6 tst-sem7 \
230
	tst-sem1 tst-sem2 tst-sem3 tst-sem4 tst-sem5 tst-sem6 tst-sem7 \
230
	tst-sem8 tst-sem9 tst-sem10 tst-sem11 tst-sem12 tst-sem13 tst-sem14 \
231
	tst-sem8 tst-sem9 tst-sem10 tst-sem11 tst-sem12 tst-sem13 tst-sem14 \
(-)a/nptl/pthread_once.c (-15 / +24 lines)
Lines 23-41 Link Here
23
23
24
unsigned long int __fork_generation attribute_hidden;
24
unsigned long int __fork_generation attribute_hidden;
25
25
26
struct CleanupInfo {
27
  pthread_once_t *once;
28
};
26
29
27
static void
30
static void
28
clear_once_control (void *arg)
31
cleanup_maybe_clear_once_control (struct CleanupInfo *pinfo)
29
{
32
{
30
  pthread_once_t *once_control = (pthread_once_t *) arg;
33
  if (pinfo->once) {
31
34
32
  /* Reset to the uninitialized state here.  We don't need a stronger memory
35
    /* Reset the once control variable to the uninitialized state here.
33
     order because we do not need to make any other of our writes visible to
36
       We don't need a stronger memory order because we do not need to
34
     other threads that see this value: This function will be called if we
37
       make any other of our writes visible to other threads that see
35
     get interrupted (see __pthread_once), so all we need to relay to other
38
       this value: This function will be called if we get interrupted
36
     threads is the state being reset again.  */
39
       (see __pthread_once), so all we need to relay to other threads
37
  atomic_store_relaxed (once_control, 0);
40
       is the state being reset again.  */
38
  lll_futex_wake (once_control, INT_MAX, LLL_PRIVATE);
41
    atomic_store_relaxed (pinfo->once, 0);
42
    lll_futex_wake (pinfo->once, INT_MAX, LLL_PRIVATE);
43
  }
39
}
44
}
40
45
41
46
Lines 107-120 __pthread_once_slow (pthread_once_t *once_control, void (*init_routine) (void)) Link Here
107
	}
112
	}
108
113
109
      /* This thread is the first here.  Do the initialization.
114
      /* This thread is the first here.  Do the initialization.
110
	 Register a cleanup handler so that in case the thread gets
115
         Register a cleanup handler so that in case the thread gets
111
	 interrupted the initialization can be restarted.  */
116
         interrupted or the initialization routine exits by throwing
112
      pthread_cleanup_push (clear_once_control, once_control);
117
         an exception the initialization can be restarted.  */
113
118
114
      init_routine ();
119
      struct CleanupInfo
120
        cleanupobj __attribute__ ((cleanup (cleanup_maybe_clear_once_control)))
121
        = { .once = once_control };
115
122
116
      pthread_cleanup_pop (0);
123
      init_routine ();
117
124
125
      /* Reset the once control variable to disable cleanup.  */
126
      cleanupobj.once = 0;
118
127
119
      /* Mark *once_control as having finished the initialization.  We need
128
      /* Mark *once_control as having finished the initialization.  We need
120
         release memory order here because we need to synchronize with other
129
         release memory order here because we need to synchronize with other
(-)a/nptl/tst-once5.cc (+80 lines)
Line 0 Link Here
1
/* Copyright (C) 2015 Free Software Foundation, Inc.
2
   This file is part of the GNU C Library.
3
   Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
4
5
   The GNU C Library is free software; you can redistribute it and/or
6
   modify it under the terms of the GNU Lesser General Public
7
   License as published by the Free Software Foundation; either
8
   version 2.1 of the License, or (at your option) any later version.
9
10
   The GNU C Library is distributed in the hope that it will be useful,
11
   but WITHOUT ANY WARRANTY; without even the implied warranty of
12
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13
   Lesser General Public License for more details.
14
15
   You should have received a copy of the GNU Lesser General Public
16
   License along with the GNU C Library; if not, see
17
   <http://www.gnu.org/licenses/>.  */
18
19
#include <errno.h>
20
#include <pthread.h>
21
#include <stdio.h>
22
#include <string.h>
23
24
25
static pthread_once_t once = PTHREAD_ONCE_INIT;
26
27
// Exception type thrown from the pthread_once init routine.
28
struct OnceException { };
29
30
// Test iteration counter.
31
static int niter;
32
33
static void
34
init_routine (void)
35
{
36
  if (niter < 2)
37
    throw OnceException ();
38
}
39
40
// Verify that an exception thrown from the pthread_once init routine
41
// is propagated to the pthread_once caller and that the function can
42
// be subsequently invoked to attempt the initialization again.
43
static int
44
do_test (void)
45
{
46
  int result = 1;
47
48
  // Repeat three times, having the init routine throw the first two
49
  // times and succeed on the final attempt.
50
  for (niter = 0; niter != 3; ++niter) {
51
52
    try {
53
      int rc = pthread_once (&once, init_routine);
54
      if (rc)
55
        fprintf (stderr, "pthread_once failed: %i (%s)\n",
56
                 rc, strerror (rc));
57
58
      if (niter < 2)
59
        fputs ("pthread_once unexpectedly returned without"
60
               " throwing an exception", stderr);
61
    }
62
    catch (OnceException) {
63
      if (1 < niter)
64
        fputs ("pthread_once unexpectedly threw", stderr);
65
      result = 0;
66
    }
67
    catch (...) {
68
      fputs ("pthread_once threw an unknown exception", stderr);
69
    }
70
71
    // Abort the test on the first failure.
72
    if (result)
73
      break;
74
  }
75
76
  return result;
77
}
78
79
#define TEST_FUNCTION do_test ()
80
#include "../test-skeleton.c"

Return to bug 18435