Back to index

glibc  2.9
sem_close.c
Go to the documentation of this file.
00001 /* Copyright (C) 2002, 2003 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 <search.h>
00022 #include <sys/mman.h>
00023 #include "semaphoreP.h"
00024 
00025 
00026 /* Global variables to parametrize the walk function.  This works
00027    since we always have to use locks.  And we have to use the twalk
00028    function since the entries are not sorted wrt the mapping
00029    address.  */
00030 static sem_t *the_sem;
00031 static struct inuse_sem *rec;
00032 
00033 static void
00034 walker (const void *inodep, const VISIT which, const int depth)
00035 {
00036   struct inuse_sem *nodep = *(struct inuse_sem **) inodep;
00037 
00038   if (nodep->sem == the_sem)
00039     rec = nodep;
00040 }
00041 
00042 
00043 int
00044 sem_close (sem)
00045      sem_t *sem;
00046 {
00047   int result = 0;
00048 
00049   /* Get the lock.  */
00050   lll_lock (__sem_mappings_lock, LLL_PRIVATE);
00051 
00052   /* Locate the entry for the mapping the caller provided.  */
00053   rec = NULL;
00054   the_sem = sem;
00055   twalk (__sem_mappings, walker);
00056   if  (rec != NULL)
00057     {
00058       /* Check the reference counter.  If it is going to be zero, free
00059         all the resources.  */
00060       if (--rec->refcnt == 0)
00061        {
00062          /* Remove the record from the tree.  */
00063          (void) tdelete (rec, &__sem_mappings, __sem_search);
00064 
00065          result = munmap (rec->sem, sizeof (sem_t));
00066 
00067          free (rec);
00068        }
00069     }
00070   else
00071     {
00072       /* This is no valid semaphore.  */
00073       result = -1;
00074       __set_errno (EINVAL);
00075     }
00076 
00077   /* Release the lock.  */
00078   lll_unlock (__sem_mappings_lock, LLL_PRIVATE);
00079 
00080   return result;
00081 }