Back to index

glibc  2.9
td_ta_tsd_iter.c
Go to the documentation of this file.
00001 /* Iterate over a process's thread-specific data.
00002    Copyright (C) 1999,2000,2001,2002,2003 Free Software Foundation, Inc.
00003    This file is part of the GNU C Library.
00004    Contributed by Ulrich Drepper <drepper@redhat.com>, 1999.
00005 
00006    The GNU C Library is free software; you can redistribute it and/or
00007    modify it under the terms of the GNU Lesser General Public
00008    License as published by the Free Software Foundation; either
00009    version 2.1 of the License, or (at your option) any later version.
00010 
00011    The GNU C Library is distributed in the hope that it will be useful,
00012    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014    Lesser General Public License for more details.
00015 
00016    You should have received a copy of the GNU Lesser General Public
00017    License along with the GNU C Library; if not, write to the Free
00018    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
00019    02111-1307 USA.  */
00020 
00021 #include "thread_dbP.h"
00022 #include <alloca.h>
00023 
00024 td_err_e
00025 td_ta_tsd_iter (const td_thragent_t *ta_arg, td_key_iter_f *callback,
00026               void *cbdata_p)
00027 {
00028   td_thragent_t *const ta = (td_thragent_t *) ta_arg;
00029   td_err_e err;
00030   void *keys;
00031   size_t keys_nb, keys_elemsize;
00032   psaddr_t addr;
00033   uint32_t idx;
00034 
00035   LOG ("td_ta_tsd_iter");
00036 
00037   /* Test whether the TA parameter is ok.  */
00038   if (! ta_ok (ta))
00039     return TD_BADTA;
00040 
00041   /* This makes sure we have the size information on hand.  */
00042   addr = 0;
00043   err = _td_locate_field (ta,
00044                        ta->ta_var___pthread_keys, SYM_DESC___pthread_keys,
00045                        (psaddr_t) 0 + 1, &addr);
00046   if (err != TD_OK)
00047     return err;
00048 
00049   /* Now copy in the entire array of key descriptors.  */
00050   keys_elemsize = (addr - (psaddr_t) 0) / 8;
00051   keys_nb = keys_elemsize * DB_DESC_NELEM (ta->ta_var___pthread_keys);
00052   keys = __alloca (keys_nb);
00053   err = DB_GET_SYMBOL (addr, ta, __pthread_keys);
00054   if (err != TD_OK)
00055     return err;
00056   if (ps_pdread (ta->ph, addr, keys, keys_nb) != PS_OK)
00057     return TD_ERR;
00058 
00059   /* Now get all descriptors, one after the other.  */
00060   for (idx = 0; idx < DB_DESC_NELEM (ta->ta_var___pthread_keys); ++idx)
00061     {
00062       psaddr_t seq, destr;
00063       err = DB_GET_FIELD_LOCAL (seq, ta, keys, pthread_key_struct, seq, 0);
00064       if (err != TD_OK)
00065        return err;
00066       if (((uintptr_t) seq) & 1)
00067        {
00068          err = DB_GET_FIELD_LOCAL (destr, ta, keys, pthread_key_struct,
00069                                 destr, 0);
00070          if (err != TD_OK)
00071            return err;
00072          /* Return with an error if the callback returns a nonzero value.  */
00073          if (callback ((thread_key_t) idx, destr, cbdata_p) != 0)
00074            return TD_DBERR;
00075        }
00076       /* Advance to the next element in the copied array.  */
00077       keys += keys_elemsize;
00078     }
00079 
00080   return TD_OK;
00081 }