From: Ulrich Drepper Date: Sat, 17 May 2003 20:49:02 +0000 (+0000) Subject: Fix one endless loop. Implement correct semantics wrt opening the same semaphore... X-Git-Tag: cvs/glibc-2_3_3~711 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=68a396e83a8e1e50d0dfde8ffb090a8df311453f;p=thirdparty%2Fglibc.git Fix one endless loop. Implement correct semantics wrt opening the same semaphore more then once. --- diff --git a/nptl/sem_close.c b/nptl/sem_close.c index 379565f5185..279522d086b 100644 --- a/nptl/sem_close.c +++ b/nptl/sem_close.c @@ -1,4 +1,4 @@ -/* Copyright (C) 2002 Free Software Foundation, Inc. +/* Copyright (C) 2002, 2003 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Ulrich Drepper , 2002. @@ -17,13 +17,65 @@ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ -#include +#include +#include #include +#include "semaphoreP.h" + + +/* Global variables to parametrize the walk function. This works + since we always have to use locks. And we have to use the twalk + function since the entries are not sorted wrt the mapping + address. */ +static sem_t *the_sem; +static struct inuse_sem *rec; + +static void +walker (const void *inodep, const VISIT which, const int depth) +{ + struct inuse_sem *nodep = *(struct inuse_sem **) inodep; + + if (nodep->sem == the_sem) + rec = nodep; +} int sem_close (sem) sem_t *sem; { - return munmap (sem, sizeof (sem_t)); + int result = 0; + + /* Get the lock. */ + lll_lock (__sem_mappings_lock); + + /* Locate the entry for the mapping the caller provided. */ + rec = NULL; + the_sem = sem; + twalk (__sem_mappings, walker); + if (rec != NULL) + { + /* Check the reference counter. If it is going to be zero, free + all the resources. */ + if (--rec->refcnt == 0) + { + /* Remove the record from the tree. */ + (void) tdelete (rec, &__sem_mappings, __sem_search); + + result = munmap (rec->sem, sizeof (sem_t)); + + free (rec); + } + } + else + { + /* This is no valid semaphore. */ + result = -1; + __set_errno (EINVAL); + } + + /* Release the lock. */ + lll_unlock (__sem_mappings_lock); + + return result; }