Back to index

glibc  2.9
Classes | Functions
gai_notify.c File Reference
#include <netdb.h>
#include <pthread.h>
#include <stdlib.h>
#include <gai_misc.h>

Go to the source code of this file.


struct  notify_func


static void * notify_func_wrapper (void *arg)
int internal_function __gai_notify_only (struct sigevent *sigev, pid_t caller_pid)
void internal_function __gai_notify (struct requestlist *req)

Function Documentation

void internal_function __gai_notify ( struct requestlist req)

Definition at line 99 of file gai_notify.c.

  struct waitlist *waitlist;

  /* Now also notify possibly waiting threads.  */
  waitlist = req->waiting;
  while (waitlist != NULL)
      struct waitlist *next = waitlist->next;

      if (waitlist->sigevp == NULL)
         GAI_MISC_NOTIFY (waitlist);
         /* Decrement the counter.  */

         pthread_cond_signal (waitlist->cond);
       /* This is part of a asynchronous `getaddrinfo_a' operation.  If
          this request is the last one, send the signal.  */
       if (--*waitlist->counterp == 0)
           __gai_notify_only (waitlist->sigevp, waitlist->caller_pid);
           /* This is tricky.  See getaddrinfo_a.c for the reason why
              this works.  */
           free ((void *) waitlist->counterp);

      waitlist = next;

Here is the call graph for this function:

Here is the caller graph for this function:

int internal_function __gai_notify_only ( struct sigevent *  sigev,
pid_t  caller_pid 

Definition at line 47 of file gai_notify.c.

  int result = 0;

  /* Send the signal to notify about finished processing of the request.  */
  if (sigev->sigev_notify == SIGEV_THREAD)
      /* We have to start a thread.  */
      pthread_t tid;
      pthread_attr_t attr, *pattr;

      pattr = (pthread_attr_t *) sigev->sigev_notify_attributes;
      if (pattr == NULL)
         pthread_attr_init (&attr);
         pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED);
         pattr = &attr;

      /* SIGEV may be freed as soon as we return, so we cannot let the
        notification thread use that pointer.  Even though a sigval_t is
        only one word and the same size as a void *, we cannot just pass
        the value through pthread_create as the argument and have the new
        thread run the user's function directly, because on some machines
        the calling convention for a union like sigval_t is different from
        that for a pointer type like void *.  */
      struct notify_func *nf = malloc (sizeof *nf);
      if (nf == NULL)
       result = -1;
         nf->func = sigev->sigev_notify_function;
         nf->value = sigev->sigev_value;
         if (pthread_create (&tid, pattr, notify_func_wrapper, nf) < 0)
             free (nf);
             result = -1;
  else if (sigev->sigev_notify == SIGEV_SIGNAL)
    /* We have to send a signal.  */
    if (__gai_sigqueue (sigev->sigev_signo, sigev->sigev_value, caller_pid)
       < 0)
      result = -1;

  return result;

Here is the call graph for this function:

Here is the caller graph for this function:

static void* notify_func_wrapper ( void *  arg) [static]

Definition at line 33 of file gai_notify.c.

  gai_start_notify_thread ();
  struct notify_func *const n = arg;
  void (*func) (sigval_t) = n->func;
  sigval_t value = n->value;
  free (n);
  (*func) (value);
  return NULL;

Here is the caller graph for this function: