[MAJOR] modularize the polling mechanisms

select, poll and epoll now have their dedicated functions and have
been split into distinct files. Several FD manipulation primitives
have been provided with each poller.

The rest of the code needs to be cleaned to remove traces of
StaticReadEvent/StaticWriteEvent. A trick involving a macro has
temporarily been used right now. Some work needs to be done to
factorize tests and sets everywhere.
This commit is contained in:
Willy Tarreau
2007-04-08 16:39:58 +02:00
parent b3107b9383
commit 4f60f16dd3
11 changed files with 1088 additions and 539 deletions

View File

@@ -2,7 +2,7 @@
include/proto/fd.h
File descriptors states.
Copyright (C) 2000-2006 Willy Tarreau - w@1wt.eu
Copyright (C) 2000-2007 Willy Tarreau - w@1wt.eu
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -34,29 +34,41 @@
*/
void fd_delete(int fd);
/* registers all known pollers */
void register_pollers();
/* disable the specified poller */
void disable_poller(const char *poller_name);
/*
* Benchmarks performed on a Pentium-M notebook show that using functions
* instead of the usual macros improve the FD_* performance by about 80%,
* and that marking them regparm(2) adds another 20%.
* Initialize the pollers till the best one is found.
* If none works, returns 0, otherwise 1.
*/
#if defined(CONFIG_HAP_INLINE_FD_SET)
int init_pollers();
# define MY_FD_SET FD_SET
# define MY_FD_CLR FD_CLR
# define MY_FD_ISSET FD_ISSET
/*
* Runs the polling loop
*/
void run_poller();
#else
# define MY_FD_SET my_fd_set
# define MY_FD_CLR my_fd_clr
# define MY_FD_ISSET my_fd_isset
/* FIXME: dirty hack during code transition */
#define dir_StaticWriteEvent DIR_WR
#define dir_StaticReadEvent DIR_RD
#define dir_DIR_RD DIR_RD
#define dir_DIR_WR DIR_WR
REGPRM2 void my_fd_set(const int fd, fd_set *ev);
REGPRM2 void my_fd_clr(const int fd, fd_set *ev);
REGPRM2 int my_fd_isset(const int fd, const fd_set *ev);
#define MY_FD_SET(fd, ev) (cur_poller.set((fd), dir_##ev))
#define MY_FD_CLR(fd, ev) (cur_poller.clr((fd), dir_##ev))
#define MY_FD_ISSET(fd, ev) (cur_poller.isset((fd), dir_##ev))
#endif
#define EV_FD_SET(fd, ev) (cur_poller.set((fd), dir_##ev))
#define EV_FD_CLR(fd, ev) (cur_poller.clr((fd), dir_##ev))
#define EV_FD_ISSET(fd, ev) (cur_poller.isset((fd), dir_##ev))
#define EV_FD_COND_S(fd, ev) (cur_poller.cond_s((fd), dir_##ev))
#define EV_FD_COND_C(fd, ev) (cur_poller.cond_c((fd), dir_##ev))
#define EV_FD_REM(fd) (cur_poller.rem(fd))
#define EV_FD_CLO(fd) (cur_poller.clo(fd))
/* recomputes the maxfd limit from the fd */

View File

@@ -53,6 +53,43 @@ struct fdtab {
int state; /* the state of this fd */
};
/*
* Poller descriptors.
* - <name> is initialized by the poller's register() function, and should not
* be allocated, just linked to.
* - <pref> is initialized by the poller's register() function. It is set to 0
* by default, meaning the poller is disabled. init() should set it to 0 in
* case of failure. term() must set it to 0. A generic unoptimized select()
* poller should set it to 100.
* - <private> is initialized by the poller's init() function, and cleaned by
* the term() function.
* - cond_s() checks if fd was not set then sets it and returns 1. Otherwise 0.
* - cond_c() checks if fd was set then clears it and returns 1. Otherwise 0.
* - clo() should be used to do indicate the poller that fd will be closed. It
* may be the same as rem() on some pollers.
* - poll() calls the poller, waiting at most wait_time ms.
*/
struct poller {
void *private; /* any private data for the poller */
REGPRM2 int (*isset)(const int fd, const int dir); /* check if <fd> is being polled for dir <dir> */
REGPRM2 void (*set)(const int fd, const int dir); /* set polling on <fd> for <dir> */
REGPRM2 void (*clr)(const int fd, const int dir); /* clear polling on <fd> for <dir> */
REGPRM2 int (*cond_s)(const int fd, const int dir); /* set polling on <fd> for <dir> if unset */
REGPRM2 int (*cond_c)(const int fd, const int dir); /* clear polling on <fd> for <dir> if set */
REGPRM1 void (*rem)(const int fd); /* remove any polling on <fd> */
REGPRM1 void (*clo)(const int fd); /* mark <fd> as closed */
REGPRM2 void (*poll)(struct poller *p, int wait_time); /* the poller itself */
REGPRM1 int (*init)(struct poller *p); /* poller initialization */
REGPRM1 void (*term)(struct poller *p); /* termination of this poller */
const char *name; /* poller name */
int pref; /* try pollers with higher preference first */
};
extern struct poller cur_poller; /* the current poller */
extern int nbpollers;
#define MAX_POLLERS 10
extern struct poller pollers[MAX_POLLERS]; /* all registered pollers */
extern struct fdtab *fdtab; /* array of all the file descriptors */
extern int maxfd; /* # of the highest fd + 1 */
extern int totalconn; /* total # of terminated sessions */

View File

@@ -2,7 +2,7 @@
include/types/polling.h
File descriptors and polling definitions.
Copyright (C) 2000-2006 Willy Tarreau - w@1wt.eu
Copyright (C) 2000-2007 Willy Tarreau - w@1wt.eu
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
@@ -53,8 +53,6 @@
#define POLL_USE_POLL (1<<1)
#define POLL_USE_EPOLL (1<<2)
/* fd states */
extern fd_set *StaticReadEvent, *StaticWriteEvent;
extern int cfg_polling_mechanism; /* POLL_USE_{SELECT|POLL|EPOLL} */