Back to index

glibc  2.9
Classes | Defines | Functions | Variables
register-atfork.c File Reference
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <fork.h>
#include <atomic.h>

Go to the source code of this file.

Classes

struct  fork_handler_pool

Defines

#define NHANDLER   48

Functions

static struct fork_handlerfork_handler_alloc (void)
int __register_atfork (void(*)(void) prepare, void(*)(void) parent, void(*)(void) child, void *dso_handle)
 libc_hidden_def (__register_atfork)
 libc_freeres_fn (free_mem)

Variables

int __fork_lock = LLL_LOCK_INITIALIZER
static struct fork_handler_pool fork_handler_pool

Class Documentation

struct fork_handler_pool

Definition at line 35 of file register-atfork.c.

Collaboration diagram for fork_handler_pool:
Class Members
struct fork_handler_pool * next

Define Documentation

#define NHANDLER   48

Definition at line 32 of file register-atfork.c.


Function Documentation

int __register_atfork ( void (*) (void)  prepare,
void (*) (void)  parent,
void (*) (void)  child,
void *  dso_handle 
)

Definition at line 82 of file register-atfork.c.

{
  /* Get the lock to not conflict with other allocations.  */
  lll_lock (__fork_lock, LLL_PRIVATE);

  struct fork_handler *newp = fork_handler_alloc ();

  if (newp != NULL)
    {
      /* Initialize the new record.  */
      newp->prepare_handler = prepare;
      newp->parent_handler = parent;
      newp->child_handler = child;
      newp->dso_handle = dso_handle;

      __linkin_atfork (newp);
    }

  /* Release the lock.  */
  lll_unlock (__fork_lock, LLL_PRIVATE);

  return newp == NULL ? ENOMEM : 0;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static struct fork_handler* fork_handler_alloc ( void  ) [static, read]

Definition at line 43 of file register-atfork.c.

{
  struct fork_handler_pool *runp = &fork_handler_pool;
  struct fork_handler *result = NULL;
  unsigned int i;

  do
    {
      /* Search for an empty entry.  */
      for (i = 0; i < NHANDLER; ++i)
       if (runp->mem[i].refcntr == 0)
         goto found;
    }
  while ((runp = runp->next) != NULL);

  /* We have to allocate a new entry.  */
  runp = (struct fork_handler_pool *) calloc (1, sizeof (*runp));
  if (runp != NULL)
    {
      /* Enqueue the new memory pool into the list.  */
      runp->next = fork_handler_pool.next;
      fork_handler_pool.next = runp;

      /* We use the last entry on the page.  This means when we start
        searching from the front the next time we will find the first
        entry unused.  */
      i = NHANDLER - 1;

    found:
      result = &runp->mem[i];
      result->refcntr = 1;
      result->need_signal = 0;
    }

  return result;
}

Here is the call graph for this function:

Here is the caller graph for this function:

libc_freeres_fn ( free_mem  )

Definition at line 123 of file register-atfork.c.

{
  /* Get the lock to not conflict with running forks.  */
  lll_lock (__fork_lock, LLL_PRIVATE);

  /* No more fork handlers.  */
  __fork_handlers = NULL;

  /* Free eventually alloated memory blocks for the object pool.  */
  struct fork_handler_pool *runp = fork_handler_pool.next;

  memset (&fork_handler_pool, '\0', sizeof (fork_handler_pool));

  /* Release the lock.  */
  lll_unlock (__fork_lock, LLL_PRIVATE);

  /* We can free the memory after releasing the lock.  */
  while (runp != NULL)
    {
      struct fork_handler_pool *oldp = runp;
      runp = runp->next;
      free (oldp);
    }
}

Definition at line 109 of file register-atfork.c.

{
  do
    newp->next = __fork_handlers;
  while (catomic_compare_and_exchange_bool_acq (&__fork_handlers,
                                          newp, newp->next) != 0);
}

Variable Documentation

Definition at line 28 of file register-atfork.c.