Back to index

glibc  2.9
Classes | Enumerations | Functions | Variables
aio_misc.h File Reference
#include <aio.h>
#include <pthread.h>
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Classes

union  aiocb_union
struct  waitlist
struct  requestlist

Enumerations

enum  { LIO_DSYNC = LIO_NOP + 1, LIO_SYNC, LIO_READ64 = LIO_READ | 128, LIO_WRITE64 = LIO_WRITE | 128 }
enum  {
  no, queued, yes, allocated,
  done
}

Functions

struct requestlist__aio_enqueue_request (aiocb_union *aiocbp, int operation) attribute_hidden internal_function
struct requestlist__aio_find_req (aiocb_union *elem) attribute_hidden internal_function
struct requestlist__aio_find_req_fd (int fildes) attribute_hidden internal_function
void __aio_remove_request (struct requestlist *last, struct requestlist *req, int all) attribute_hidden internal_function
void __aio_free_request (struct requestlist *req) attribute_hidden internal_function
void __aio_notify (struct requestlist *req) attribute_hidden internal_function
int __aio_notify_only (struct sigevent *sigev) attribute_hidden internal_function
int __aio_sigqueue (int sig, const union sigval val, pid_t caller_pid) attribute_hidden internal_function

Variables

pthread_mutex_t
__aio_requests_mutex 
attribute_hidden

Class Documentation

union aiocb_union

Definition at line 36 of file aio_misc.h.

struct waitlist

Definition at line 28 of file gai_misc.h.

Collaboration diagram for waitlist:
Class Members
pid_t caller_pid
pthread_cond_t * cond
volatile int * counterp
struct waitlist * next
int * result
struct sigevent * sigevp
struct requestlist

Definition at line 45 of file gai_misc.h.

Collaboration diagram for requestlist:
Class Members
aiocb_union * aiocbp
struct gaicb * gaicbp
struct requestlist * last_fd
struct requestlist * next
struct requestlist * next_fd
struct requestlist * next_prio
struct requestlist * next_run
int running
struct waitlist * waiting

Enumeration Type Documentation

anonymous enum
Enumerator:
LIO_DSYNC 
LIO_SYNC 
LIO_READ64 
LIO_WRITE64 

Definition at line 27 of file aio_misc.h.

anonymous enum
Enumerator:
no 
queued 
yes 
allocated 
done 

Definition at line 67 of file aio_misc.h.


Function Documentation

struct requestlist* __aio_enqueue_request ( aiocb_union aiocbp,
int  operation 
) [read]

Here is the caller graph for this function:

struct requestlist* __aio_find_req ( aiocb_union elem) [read]

Definition at line 174 of file aio_misc.c.

{
  struct requestlist *runp = requests;
  int fildes = elem->aiocb.aio_fildes;

  while (runp != NULL && runp->aiocbp->aiocb.aio_fildes < fildes)
    runp = runp->next_fd;

  if (runp != NULL)
    {
      if (runp->aiocbp->aiocb.aio_fildes != fildes)
       runp = NULL;
      else
       while (runp != NULL && runp->aiocbp != elem)
         runp = runp->next_prio;
    }

  return runp;
}

Here is the caller graph for this function:

struct requestlist* __aio_find_req_fd ( int  fildes) [read]

Definition at line 197 of file aio_misc.c.

{
  struct requestlist *runp = requests;

  while (runp != NULL && runp->aiocbp->aiocb.aio_fildes < fildes)
    runp = runp->next_fd;

  return (runp != NULL && runp->aiocbp->aiocb.aio_fildes == fildes
         ? runp : NULL);
}

Here is the caller graph for this function:

void __aio_free_request ( struct requestlist req)

Definition at line 164 of file aio_misc.c.

{
  elem->running = no;
  elem->next_prio = freelist;
  freelist = elem;
}

Here is the caller graph for this function:

void __aio_notify ( struct requestlist req)

Definition at line 123 of file aio_notify.c.

{
  struct waitlist *waitlist;
  struct aiocb *aiocbp = &req->aiocbp->aiocb;

#ifdef BROKEN_THREAD_SIGNALS
  if (__aio_notify_only (&aiocbp->aio_sigevent, req->caller_pid) != 0)
#else
  if (__aio_notify_only (&aiocbp->aio_sigevent) != 0)
#endif
    {
      /* XXX What shall we do if already an error is set by
        read/write/fsync?  */
      aiocbp->__error_code = errno;
      aiocbp->__return_value = -1;
    }

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

      if (waitlist->sigevp == NULL)
       {
         if (waitlist->result != NULL && aiocbp->__return_value == -1)
           *waitlist->result = -1;

#ifdef DONT_NEED_AIO_MISC_COND
         AIO_MISC_NOTIFY (waitlist);
#else
         /* Decrement the counter.  */
         --*waitlist->counterp;

         pthread_cond_signal (waitlist->cond);
#endif
       }
      else
       /* This is part of a asynchronous `lio_listio' operation.  If
          this request is the last one, send the signal.  */
       if (--*waitlist->counterp == 0)
         {
#ifdef BROKEN_THREAD_SIGNALS
           __aio_notify_only (waitlist->sigevp, waitlist->caller_pid);
#else
           __aio_notify_only (waitlist->sigevp);
#endif
           /* This is tricky.  See lio_listio.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 __aio_notify_only ( struct sigevent *  sigev)

Definition at line 55 of file aio_notify.c.

{
  int result = 0;

  /* Send the signal to notify about finished processing of the request.  */
  if (__builtin_expect (sigev->sigev_notify == SIGEV_THREAD, 0))
    {
      /* 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;
      else
       {
         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 _POSIX_REALTIME_SIGNALS
      /* Note that the standard gives us the option of using a plain
        non-queuing signal here when SA_SIGINFO is not set for the signal.  */
# ifdef BROKEN_THREAD_SIGNALS
      if (__aio_sigqueue (sigev->sigev_signo, sigev->sigev_value, caller_pid)
         < 0)
       result = -1;
# else
      if (__aio_sigqueue (sigev->sigev_signo, sigev->sigev_value, getpid ())
         < 0)
       result = -1;
# endif
#else
      /* There are no queued signals on this system at all.  */
      result = raise (sigev->sigev_signo);
#endif
    }

  return result;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void __aio_remove_request ( struct requestlist last,
struct requestlist req,
int  all 
)

Definition at line 211 of file aio_misc.c.

{
  assert (req->running == yes || req->running == queued
         || req->running == done);

  if (last != NULL)
    last->next_prio = all ? NULL : req->next_prio;
  else
    {
      if (all || req->next_prio == NULL)
       {
         if (req->last_fd != NULL)
           req->last_fd->next_fd = req->next_fd;
         else
           requests = req->next_fd;
         if (req->next_fd != NULL)
           req->next_fd->last_fd = req->last_fd;
       }
      else
       {
         if (req->last_fd != NULL)
           req->last_fd->next_fd = req->next_prio;
         else
           requests = req->next_prio;

         if (req->next_fd != NULL)
           req->next_fd->last_fd = req->next_prio;

         req->next_prio->last_fd = req->last_fd;
         req->next_prio->next_fd = req->next_fd;

         /* Mark this entry as runnable.  */
         req->next_prio->running = yes;
       }

      if (req->running == yes)
       {
         struct requestlist *runp = runlist;

         last = NULL;
         while (runp != NULL)
           {
             if (runp == req)
              {
                if (last == NULL)
                  runlist = runp->next_run;
                else
                  last->next_run = runp->next_run;
                break;
              }
             last = runp;
             runp = runp->next_run;
           }
       }
    }
}

Here is the caller graph for this function:

int __aio_sigqueue ( int  sig,
const union sigval  val,
pid_t  caller_pid 
)

Definition at line 26 of file aio_sigqueue.c.

{
  __set_errno (ENOSYS);
  return -1;
}

Here is the caller graph for this function:


Variable Documentation

Definition at line 25 of file init-first.c.