Back to index

glibc  2.9
pthread_cond_destroy.c
Go to the documentation of this file.
00001 /* Copyright (C) 2002, 2003, 2004, 2007 Free Software Foundation, Inc.
00002    This file is part of the GNU C Library.
00003    Contributed by Ulrich Drepper <drepper@redhat.com>, 2002.
00004 
00005    The GNU C Library is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU Lesser General Public
00007    License as published by the Free Software Foundation; either
00008    version 2.1 of the License, or (at your option) any later version.
00009 
00010    The GNU C Library is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013    Lesser General Public License for more details.
00014 
00015    You should have received a copy of the GNU Lesser General Public
00016    License along with the GNU C Library; if not, write to the Free
00017    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
00018    02111-1307 USA.  */
00019 
00020 #include <errno.h>
00021 #include <shlib-compat.h>
00022 #include "pthreadP.h"
00023 
00024 
00025 int
00026 __pthread_cond_destroy (cond)
00027      pthread_cond_t *cond;
00028 {
00029   int pshared = (cond->__data.__mutex == (void *) ~0l)
00030               ? LLL_SHARED : LLL_PRIVATE;
00031 
00032   /* Make sure we are alone.  */
00033   lll_lock (cond->__data.__lock, pshared);
00034 
00035   if (cond->__data.__total_seq > cond->__data.__wakeup_seq)
00036     {
00037       /* If there are still some waiters which have not been
00038         woken up, this is an application bug.  */
00039       lll_unlock (cond->__data.__lock, pshared);
00040       return EBUSY;
00041     }
00042 
00043   /* Tell pthread_cond_*wait that this condvar is being destroyed.  */
00044   cond->__data.__total_seq = -1ULL;
00045 
00046   /* If there are waiters which have been already signalled or
00047      broadcasted, but still are using the pthread_cond_t structure,
00048      pthread_cond_destroy needs to wait for them.  */
00049   unsigned int nwaiters = cond->__data.__nwaiters;
00050 
00051   if (nwaiters >= (1 << COND_NWAITERS_SHIFT))
00052     {
00053       /* Wake everybody on the associated mutex in case there are
00054          threads that have been requeued to it.
00055          Without this, pthread_cond_destroy could block potentially
00056          for a long time or forever, as it would depend on other
00057          thread's using the mutex.
00058          When all threads waiting on the mutex are woken up, pthread_cond_wait
00059          only waits for threads to acquire and release the internal
00060          condvar lock.  */
00061       if (cond->__data.__mutex != NULL
00062          && cond->__data.__mutex != (void *) ~0l)
00063        {
00064          pthread_mutex_t *mut = (pthread_mutex_t *) cond->__data.__mutex;
00065          lll_futex_wake (&mut->__data.__lock, INT_MAX,
00066                        PTHREAD_MUTEX_PSHARED (mut));
00067        }
00068 
00069       do
00070        {
00071          lll_unlock (cond->__data.__lock, pshared);
00072 
00073          lll_futex_wait (&cond->__data.__nwaiters, nwaiters, pshared);
00074 
00075          lll_lock (cond->__data.__lock, pshared);
00076 
00077          nwaiters = cond->__data.__nwaiters;
00078        }
00079       while (nwaiters >= (1 << COND_NWAITERS_SHIFT));
00080     }
00081 
00082   return 0;
00083 }
00084 versioned_symbol (libpthread, __pthread_cond_destroy,
00085                 pthread_cond_destroy, GLIBC_2_3_2);