fdwalk should return 0 on an empty directory
[kopensolaris-gnu/glibc.git] / nptl / cancellation.c
1 /* Copyright (C) 2002, 2003 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, write to the Free
17    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18    02111-1307 USA.  */
19
20 #include <setjmp.h>
21 #include <stdlib.h>
22 #include "pthreadP.h"
23
24
25 /* The next two functions are similar to pthread_setcanceltype() but
26    more specialized for the use in the cancelable functions like write().
27    They do not need to check parameters etc.  */
28 int
29 attribute_hidden
30 __pthread_enable_asynccancel (void)
31 {
32   struct pthread *self = THREAD_SELF;
33   int oldval = THREAD_GETMEM (self, cancelhandling);
34
35   while (1)
36     {
37       int newval = oldval | CANCELTYPE_BITMASK;
38
39       if (newval == oldval)
40         break;
41
42       int curval = THREAD_ATOMIC_CMPXCHG_VAL (self, cancelhandling, newval,
43                                               oldval);
44       if (__builtin_expect (curval == oldval, 1))
45         {
46           if (CANCEL_ENABLED_AND_CANCELED_AND_ASYNCHRONOUS (newval))
47             {
48               THREAD_SETMEM (self, result, PTHREAD_CANCELED);
49               __do_cancel ();
50             }
51
52           break;
53         }
54
55       /* Prepare the next round.  */
56       oldval = curval;
57     }
58
59   return oldval;
60 }
61
62
63 void
64 internal_function attribute_hidden
65 __pthread_disable_asynccancel (int oldtype)
66 {
67   /* If asynchronous cancellation was enabled before we do not have
68      anything to do.  */
69   if (oldtype & CANCELTYPE_BITMASK)
70     return;
71
72   struct pthread *self = THREAD_SELF;
73   int oldval = THREAD_GETMEM (self, cancelhandling);
74
75   while (1)
76     {
77       int newval = oldval & ~CANCELTYPE_BITMASK;
78
79       if (newval == oldval)
80         break;
81
82       int curval = THREAD_ATOMIC_CMPXCHG_VAL (self, cancelhandling, newval,
83                                               oldval);
84       if (__builtin_expect (curval == oldval, 1))
85         break;
86
87       /* Prepare the next round.  */
88       oldval = curval;
89     }
90 }