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

glibc/2.7/nptl/pthread_cond_destroy.c

    1: /* Copyright (C) 2002, 2003, 2004, 2007 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 <errno.h>
   21: #include <shlib-compat.h>
   22: #include "pthreadP.h"
   23: 
   24: 
   25: int
   26: __pthread_cond_destroy (cond)
   27:      pthread_cond_t *cond;
   28: {
   29:   int pshared = (cond->__data.__mutex == (void *) ~0l)
   30:                 ? LLL_SHARED : LLL_PRIVATE;
   31: 
   32:   /* Make sure we are alone.  */
   33:   lll_lock (cond->__data.__lock, pshared);
   34: 
   35:   if (cond->__data.__total_seq > cond->__data.__wakeup_seq)
   36:     {
   37:       /* If there are still some waiters which have not been
   38:          woken up, this is an application bug.  */
   39:       lll_unlock (cond->__data.__lock, pshared);
   40:       return EBUSY;
   41:     }
   42: 
   43:   /* Tell pthread_cond_*wait that this condvar is being destroyed.  */
   44:   cond->__data.__total_seq = -1ULL;
   45: 
   46:   /* If there are waiters which have been already signalled or
   47:      broadcasted, but still are using the pthread_cond_t structure,
   48:      pthread_cond_destroy needs to wait for them.  */
   49:   unsigned int nwaiters = cond->__data.__nwaiters;
   50: 
   51:   if (nwaiters >= (1 << COND_NWAITERS_SHIFT))
   52:     {
   53:       /* Wake everybody on the associated mutex in case there are
   54:          threads that have been requeued to it.
   55:          Without this, pthread_cond_destroy could block potentially
   56:          for a long time or forever, as it would depend on other
   57:          thread's using the mutex.
   58:          When all threads waiting on the mutex are woken up, pthread_cond_wait
   59:          only waits for threads to acquire and release the internal
   60:          condvar lock.  */
   61:       if (cond->__data.__mutex != NULL
   62:           && cond->__data.__mutex != (void *) ~0l)
   63:         {
   64:           pthread_mutex_t *mut = (pthread_mutex_t *) cond->__data.__mutex;
   65:           lll_futex_wake (&mut->__data.__lock, INT_MAX,
   66:                           PTHREAD_MUTEX_PSHARED (mut));
   67:         }
   68: 
   69:       do
   70:         {
   71:           lll_unlock (cond->__data.__lock, pshared);
   72: 
   73:           lll_futex_wait (&cond->__data.__nwaiters, nwaiters, pshared);
   74: 
   75:           lll_lock (cond->__data.__lock, pshared);
   76: 
   77:           nwaiters = cond->__data.__nwaiters;
   78:         }
   79:       while (nwaiters >= (1 << COND_NWAITERS_SHIFT));
   80:     }
   81: 
   82:   return 0;
   83: }
   84: versioned_symbol (libpthread, __pthread_cond_destroy,
   85:                   pthread_cond_destroy, GLIBC_2_3_2);
Syntax (Markdown)