Back to index

glibc  2.9
Functions
cxa_atexit.c File Reference
#include <assert.h>
#include <stdlib.h>
#include <bits/libc-lock.h>
#include "exit.h"
#include <atomic.h>
#include <sysdep.h>

Go to the source code of this file.

Functions

int __cxa_atexit (void(*func)(void *), void *arg, void *d)
 __libc_lock_define_initialized (static, lock)

Function Documentation

int __cxa_atexit ( void(*)(void *)  func,
void *  arg,
void *  d 
)

Definition at line 33 of file cxa_atexit.c.

{
  struct exit_function *new = __new_exitfn ();

  if (new == NULL)
    return -1;

#ifdef PTR_MANGLE
  PTR_MANGLE (func);
#endif
  new->func.cxa.fn = (void (*) (void *, int)) func;
  new->func.cxa.arg = arg;
  new->func.cxa.dso_handle = d;
  atomic_write_barrier ();
  new->flavor = ef_cxa;
  return 0;
}

Here is the call graph for this function:

__libc_lock_define_initialized ( static  ,
lock   
)

Definition at line 54 of file cxa_atexit.c.

{
  struct exit_function_list *p = NULL;
  struct exit_function_list *l;
  struct exit_function *r = NULL;
  size_t i = 0;

  __libc_lock_lock (lock);

  for (l = __exit_funcs; l != NULL; p = l, l = l->next)
    {
      for (i = l->idx; i > 0; --i)
       if (l->fns[i - 1].flavor != ef_free)
         break;

      if (i > 0)
       break;

      /* This block is completely unused.  */
      l->idx = 0;
    }

  if (l == NULL || i == sizeof (l->fns) / sizeof (l->fns[0]))
    {
      /* The last entry in a block is used.  Use the first entry in
        the previous block if it exists.  Otherwise create a new one.  */
      if (p == NULL)
       {
         assert (l != NULL);
         p = (struct exit_function_list *)
           calloc (1, sizeof (struct exit_function_list));
         if (p != NULL)
           {
             p->next = __exit_funcs;
             __exit_funcs = p;
           }
       }

      if (p != NULL)
       {
         r = &p->fns[0];
         p->idx = 1;
       }
    }
  else
    {
      /* There is more room in the block.  */
      r = &l->fns[i];
      l->idx = i + 1;
    }

  /* Mark entry as used, but we don't know the flavor now.  */
  if (r != NULL)
    {
      r->flavor = ef_us;
      ++__new_exitfn_called;
    }

  __libc_lock_unlock (lock);

  return r;
}

Here is the call graph for this function: