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

engine_select.c

/*
 * RageIRCd: an advanced Internet Relay Chat daemon (ircd).
 * (C) 2000-2005 the RageIRCd Development Team, all rights reserved.
 *
 * This software is free, licensed under the General Public License.
 * Please refer to doc/LICENSE and doc/README for further details.
 *
 * $Id: engine_select.c,v 1.18.2.4 2005/06/24 19:06:18 amcwilliam Exp $
 */

#include "setup.h"
#include "struct.h"
#include "common.h"
#include "sys.h"
#include "h.h"
#include "fd.h"
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>

#ifdef USE_SELECT

static fd_set select_read_fds;
static fd_set select_write_fds;

static void select_update_fds(int fd, short event, FDCB *cb)
{
      if (event & FDEV_READ) {
            if (cb != NULL) {
                  FD_SET(fd, &select_read_fds);
            }
            else {
                  FD_CLR(fd, &select_read_fds);
            }
      }
      if (event & FDEV_WRITE) {
            if (cb != NULL) {
                  FD_SET(fd, &select_write_fds);
            }
            else {
                  FD_CLR(fd, &select_write_fds);
            }
      }
}

void engine_init()
{
      FD_ZERO(&select_read_fds);
      FD_ZERO(&select_write_fds);
}

void engine_set_call(int fd, unsigned short flags, FDCB *cb, void *data, time_t timeout)
{
      fd_entry *fde = &fd_table[fd];

      if (flags & FDEV_READ) {
            SetCallback(fde->read, cb, data);
            select_update_fds(fd, FDEV_READ, cb);
      }
      if (flags & FDEV_WRITE) {
            SetCallback(fde->write, cb, data);
            select_update_fds(fd, FDEV_WRITE, cb);
      }
      if (timeout) {
            fde->timeout_time = timeofday + (timeout / 1000);
      }
}

void engine_do_netio(time_t delay)
{
      int cnt, i;
      fd_set read_set, write_set;
      struct timeval tv;
      fd_entry *fde;
      FDCB *cb;
      void *data;

      memcpy(&read_set, &select_read_fds, sizeof(fd_set));
      memcpy(&write_set, &select_write_fds, sizeof(fd_set));

      for (;;) {
            tv.tv_sec = 0;
            tv.tv_usec = (delay * 1000);

            if ((cnt = select(fds.highest + 1, &read_set, &write_set, NULL, &tv)) >= 0) {
                  break;
            }
            if (engine_ignore_errno(errno)) {
                  continue;
            }

            set_time();
            return;
      }

      set_time();

      if (!cnt) {
            return;
      }

      for (i = 0; i < fds.highest + 1; i++) {
            fde = &fd_table[i];

            if (FD_ISSET(i, &read_set)) {
                  GetCallback(fde->read, cb, data);
                  ClrCallback(fde->read);

                  select_update_fds(i, FDEV_READ, NULL);

                  if (cb != NULL) {
                        cb(i, data, ENGINE_OK);
                  }
            }

            if (FD_ISSET(i, &write_set)) {
                  GetCallback(fde->write, cb, data);
                  ClrCallback(fde->write);

                  select_update_fds(i, FDEV_WRITE, NULL);

                  if (cb != NULL) {
                        cb(i, data, ENGINE_OK);
                  }
            }
      }
}

#endif

Generated by  Doxygen 1.6.0   Back to index