Logo Search packages:      
Sourcecode: haproxy version File versions  Download package

fd.c

/*
 * File descriptors management functions.
 *
 * Copyright 2000-2007 Willy Tarreau <w@1wt.eu>
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version
 * 2 of the License, or (at your option) any later version.
 *
 */

#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>

#include <common/compat.h>
#include <common/config.h>

#include <types/fd.h>
#include <types/global.h>

#include <proto/fd.h>

struct fdtab *fdtab = NULL;     /* array of all the file descriptors */
int maxfd;                      /* # of the highest fd + 1 */
int totalconn;                  /* total # of terminated sessions */
int actconn;                    /* # of active sessions */

int cfg_polling_mechanism = 0;  /* POLL_USE_{SELECT|POLL|EPOLL} */

struct poller pollers[MAX_POLLERS];
struct poller cur_poller;
int nbpollers = 0;


/* Deletes an FD from the fdsets, and recomputes the maxfd limit.
 * The file descriptor is also closed.
 */
void fd_delete(int fd)
{
      EV_FD_CLO(fd);
      close(fd);
      fdtab[fd].state = FD_STCLOSE;

      while ((maxfd-1 >= 0) && (fdtab[maxfd-1].state == FD_STCLOSE))
            maxfd--;
}


/* disable the specified poller */
void disable_poller(const char *poller_name)
{
      int p;

      for (p = 0; p < nbpollers; p++)
            if (strcmp(pollers[p].name, poller_name) == 0)
                  pollers[p].pref = 0;
}

/*
 * Initialize the pollers till the best one is found.
 * If none works, returns 0, otherwise 1.
 */
int init_pollers()
{
      int p;
      struct poller *bp;


      do {
            bp = NULL;
            for (p = 0; p < nbpollers; p++)
                  if (!bp || (pollers[p].pref > bp->pref))
                        bp = &pollers[p];

            if (!bp || bp->pref == 0)
                  break;

            if (bp->init(bp)) {
                  memcpy(&cur_poller, bp, sizeof(*bp));
                  return 1;
            }
      } while (!bp || bp->pref == 0);
      return 0;
}

/*
 * Lists the known pollers on <out>.
 * Should be performed only before initialization.
 */
int list_pollers(FILE *out)
{
      int p;
      int last, next;
      int usable;
      struct poller *bp;

      fprintf(out, "Available polling systems :\n");

      usable = 0;
      bp = NULL;
      last = next = -1;
      while (1) {
            for (p = 0; p < nbpollers; p++) {
                  if (!bp || (pollers[p].pref > bp->pref))
                        bp = &pollers[p];
                  if ((next < 0 || pollers[p].pref > next)
                      && (last < 0 || pollers[p].pref < last))
                        next = pollers[p].pref;
            }

            if (next == -1)
                  break;

            for (p = 0; p < nbpollers; p++) {
                  if (pollers[p].pref == next) {
                        fprintf(out, " %10s : ", pollers[p].name);
                        if (pollers[p].pref == 0)
                              fprintf(out, "disabled, ");
                        else
                              fprintf(out, "pref=%3d, ", pollers[p].pref);
                        if (pollers[p].test(&pollers[p])) {
                              fprintf(out, " test result OK");
                              if (next > 0)
                                    usable++;
                        } else
                              fprintf(out, " test result FAILED");
                        fprintf(out, "\n");
                  }
            }
            last = next;
            next = -1;
      };
      fprintf(out, "Total: %d (%d usable), will use %s.\n", nbpollers, usable, bp ? bp->name : "none");
      return 0;
}

/*
 * Some pollers may lose their connection after a fork(). It may be necessary
 * to create initialize part of them again. Returns 0 in case of failure,
 * otherwise 1. The fork() function may be NULL if unused. In case of error,
 * the the current poller is destroyed and the caller is responsible for trying
 * another one by calling init_pollers() again.
 */
int fork_poller()
{
      if (cur_poller.fork) {
            if (cur_poller.fork(&cur_poller))
                  return 1;
            cur_poller.term(&cur_poller);
            return 0;
      }
      return 1;
}

/*
 * Local variables:
 *  c-indent-level: 8
 *  c-basic-offset: 8
 * End:
 */

Generated by  Doxygen 1.6.0   Back to index