(linenum→info "unix/slp.c:2238")

glibc/2.7/nptl/libc-cancellation.c

    1: /* Copyright (C) 2002, 2003, 2005 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: #include <atomic.h>
   24: #include <bits/libc-lock.h>
   25: 
   26: 
   27: #ifndef NOT_IN_libc
   28: 
   29: /* The next two functions are similar to pthread_setcanceltype() but
   30:    more specialized for the use in the cancelable functions like write().
   31:    They do not need to check parameters etc.  */
   32: int
   33: attribute_hidden
   34: __libc_enable_asynccancel (void)
   35: {
   36:   struct pthread *self = THREAD_SELF;
   37:   int oldval = THREAD_GETMEM (self, cancelhandling);
   38: 
   39:   while (1)
   40:     {
   41:       int newval = oldval | CANCELTYPE_BITMASK;
   42: 
   43:       if (__builtin_expect ((oldval & CANCELED_BITMASK) != 0, 0))
   44:         {
   45:           /* If we are already exiting or if PTHREAD_CANCEL_DISABLED,
   46:              stop right here.  */
   47:           if ((oldval & (EXITING_BITMASK | CANCELSTATE_BITMASK)) != 0)
   48:             break;
   49: 
   50:           int curval = THREAD_ATOMIC_CMPXCHG_VAL (self, cancelhandling,
   51:                                                   newval, oldval);
   52:           if (__builtin_expect (curval != oldval, 0))
   53:             {
   54:               /* Somebody else modified the word, try again.  */
   55:               oldval = curval;
   56:               continue;
   57:             }
   58: 
   59:           THREAD_SETMEM (self, result, PTHREAD_CANCELED);
   60: 
   61:           __do_cancel ();
   62: 
   63:           /* NOTREACHED */
   64:         }
   65: 
   66:       int curval = THREAD_ATOMIC_CMPXCHG_VAL (self, cancelhandling, newval,
   67:                                               oldval);
   68:       if (__builtin_expect (curval == oldval, 1))
   69:         break;
   70: 
   71:       /* Prepare the next round.  */
   72:       oldval = curval;
   73:     }
   74: 
   75:   return oldval;
   76: }
   77: 
   78: 
   79: void
   80: internal_function attribute_hidden
   81: __libc_disable_asynccancel (int oldtype)
   82: {
   83:   /* If asynchronous cancellation was enabled before we do not have
   84:      anything to do.  */
   85:   if (oldtype & CANCELTYPE_BITMASK)
   86:     return;
   87: 
   88:   struct pthread *self = THREAD_SELF;
   89:   int oldval = THREAD_GETMEM (self, cancelhandling);
   90: 
   91:   while (1)
   92:     {
   93:       int newval = oldval & ~CANCELTYPE_BITMASK;
   94: 
   95:       if (newval == oldval)
   96:         break;
   97: 
   98:       int curval = THREAD_ATOMIC_CMPXCHG_VAL (self, cancelhandling, newval,
   99:                                               oldval);
  100:       if (__builtin_expect (curval == oldval, 1))
  101:         break;
  102: 
  103:       /* Prepare the next round.  */
  104:       oldval = curval;
  105:     }
  106: }
  107: 
  108: 
  109: void
  110: __libc_cleanup_routine (struct __pthread_cleanup_frame *f)
  111: {
  112:   if (f->__do_it)
  113:     f->__cancel_routine (f->__cancel_arg);
  114: }
  115: 
  116: #endif
Syntax (Markdown)