*/
void fd_delete(int fd);
-/* registers all known pollers */
-void register_pollers();
-
/* disable the specified poller */
void disable_poller(const char *poller_name);
/*
* Initialize the pollers till the best one is found.
* If none works, returns 0, otherwise 1.
+ * The pollers register themselves just before main() is called.
*/
int init_pollers();
/*
* epoll() poller
*/
-REGPRM2 static void epoll_poll(struct poller *p, int wait_time)
+REGPRM2 static void _do_poll(struct poller *p, int wait_time)
{
int status;
int fd;
* Returns 0 in case of failure, non-zero in case of success. If it fails, it
* disables the poller by setting its pref to 0.
*/
-REGPRM1 static int epoll_init(struct poller *p)
+REGPRM1 static int _do_init(struct poller *p)
{
__label__ fail_chg_ptr, fail_chg_list, fail_fdevt, fail_ee, fail_fd;
int fd_set_bytes;
* Termination of the epoll() poller.
* Memory is released and the poller is marked as unselectable.
*/
-REGPRM1 static void epoll_term(struct poller *p)
+REGPRM1 static void _do_term(struct poller *p)
{
fd_flush_changes();
* Check that the poller works.
* Returns 1 if OK, otherwise 0.
*/
-REGPRM1 static int epoll_test(struct poller *p)
+REGPRM1 static int _do_test(struct poller *p)
{
int fd;
}
/*
- * The only exported function. Returns 1.
+ * It is a constructor, which means that it will automatically be called before
+ * main(). This is GCC-specific but it works at least since 2.95.
+ * Special care must be taken so that it does not need any uninitialized data.
*/
-int epoll_register(struct poller *p)
+__attribute__((constructor))
+static void _do_register(void)
{
+ struct poller *p;
+
+ if (nbpollers >= MAX_POLLERS)
+ return;
+ p = &pollers[nbpollers++];
+
p->name = "epoll";
p->pref = 300;
p->private = NULL;
- p->test = epoll_test;
- p->init = epoll_init;
- p->term = epoll_term;
- p->poll = epoll_poll;
+ p->test = _do_test;
+ p->init = _do_init;
+ p->term = _do_term;
+ p->poll = _do_poll;
p->is_set = __fd_is_set;
p->cond_s = p->set = __fd_set;
p->cond_c = p->clr = __fd_clr;
p->rem = __fd_rem;
p->clo = __fd_clo;
-
- return 1;
}
/*
* kqueue() poller
*/
-REGPRM2 static void kqueue_poll(struct poller *p, int wait_time)
+REGPRM2 static void _do_poll(struct poller *p, int wait_time)
{
int status;
int count, fd;
* Returns 0 in case of failure, non-zero in case of success. If it fails, it
* disables the poller by setting its pref to 0.
*/
-REGPRM1 static int kqueue_init(struct poller *p)
+REGPRM1 static int _do_init(struct poller *p)
{
__label__ fail_wevt, fail_revt, fail_fd;
int fd_set_bytes;
* Termination of the kqueue() poller.
* Memory is released and the poller is marked as unselectable.
*/
-REGPRM1 static void kqueue_term(struct poller *p)
+REGPRM1 static void _do_term(struct poller *p)
{
if (fd_evts[DIR_WR])
free(fd_evts[DIR_WR]);
* Check that the poller works.
* Returns 1 if OK, otherwise 0.
*/
-REGPRM1 static int kqueue_test(struct poller *p)
+REGPRM1 static int _do_test(struct poller *p)
{
int fd;
* otherwise 0. Note that some pollers need to be reopened after a fork()
* (such as kqueue), and some others may fail to do so in a chroot.
*/
-REGPRM1 static int kqueue_fork(struct poller *p)
+REGPRM1 static int _do_fork(struct poller *p)
{
close(kqueue_fd);
kqueue_fd = kqueue();
}
/*
- * The only exported function. Returns 1.
+ * It is a constructor, which means that it will automatically be called before
+ * main(). This is GCC-specific but it works at least since 2.95.
+ * Special care must be taken so that it does not need any uninitialized data.
*/
-int kqueue_register(struct poller *p)
+__attribute__((constructor))
+static void _do_register(void)
{
+ struct poller *p;
+
+ if (nbpollers >= MAX_POLLERS)
+ return;
+ p = &pollers[nbpollers++];
+
p->name = "kqueue";
p->pref = 300;
p->private = NULL;
- p->test = kqueue_test;
- p->init = kqueue_init;
- p->term = kqueue_term;
- p->poll = kqueue_poll;
- p->fork = kqueue_fork;
+ p->test = _do_test;
+ p->init = _do_init;
+ p->term = _do_term;
+ p->poll = _do_poll;
+ p->fork = _do_fork;
p->is_set = __fd_is_set;
p->cond_s = p->set = __fd_set;
p->cond_c = p->clr = __fd_clr;
p->rem = __fd_rem;
p->clo = __fd_clo;
-
- return 1;
}
/*
* Poll() poller
*/
-REGPRM2 static void poll_poll(struct poller *p, int wait_time)
+REGPRM2 static void _do_poll(struct poller *p, int wait_time)
{
int status;
int fd, nbfd;
* Returns 0 in case of failure, non-zero in case of success. If it fails, it
* disables the poller by setting its pref to 0.
*/
-REGPRM1 static int poll_init(struct poller *p)
+REGPRM1 static int _do_init(struct poller *p)
{
__label__ fail_swevt, fail_srevt, fail_pe;
int fd_set_bytes;
* Termination of the poll() poller.
* Memory is released and the poller is marked as unselectable.
*/
-REGPRM1 static void poll_term(struct poller *p)
+REGPRM1 static void _do_term(struct poller *p)
{
if (fd_evts[DIR_WR])
free(fd_evts[DIR_WR]);
* Check that the poller works.
* Returns 1 if OK, otherwise 0.
*/
-REGPRM1 static int poll_test(struct poller *p)
+REGPRM1 static int _do_test(struct poller *p)
{
return 1;
}
/*
- * The only exported function. Returns 1.
+ * It is a constructor, which means that it will automatically be called before
+ * main(). This is GCC-specific but it works at least since 2.95.
+ * Special care must be taken so that it does not need any uninitialized data.
*/
-int poll_register(struct poller *p)
+__attribute__((constructor))
+static void _do_register(void)
{
+ struct poller *p;
+
+ if (nbpollers >= MAX_POLLERS)
+ return;
+ p = &pollers[nbpollers++];
+
p->name = "poll";
p->pref = 200;
p->private = NULL;
- p->test = poll_test;
- p->init = poll_init;
- p->term = poll_term;
- p->poll = poll_poll;
+ p->test = _do_test;
+ p->init = _do_init;
+ p->term = _do_term;
+ p->poll = _do_poll;
p->is_set = __fd_is_set;
p->set = __fd_set;
p->clr = __fd_clr;
p->clo = p->rem = __fd_rem;
p->cond_s = __fd_cond_s;
p->cond_c = __fd_cond_c;
- return 1;
}
/*
* Select() poller
*/
-REGPRM2 static void select_poll(struct poller *p, int wait_time)
+REGPRM2 static void _do_poll(struct poller *p, int wait_time)
{
int status;
int fd, i;
* Returns 0 in case of failure, non-zero in case of success. If it fails, it
* disables the poller by setting its pref to 0.
*/
-REGPRM1 static int select_init(struct poller *p)
+REGPRM1 static int _do_init(struct poller *p)
{
__label__ fail_swevt, fail_srevt, fail_wevt, fail_revt;
int fd_set_bytes;
* Termination of the select() poller.
* Memory is released and the poller is marked as unselectable.
*/
-REGPRM1 static void select_term(struct poller *p)
+REGPRM1 static void _do_term(struct poller *p)
{
if (fd_evts[DIR_WR])
free(fd_evts[DIR_WR]);
* Check that the poller works.
* Returns 1 if OK, otherwise 0.
*/
-REGPRM1 static int select_test(struct poller *p)
+REGPRM1 static int _do_test(struct poller *p)
{
return 1;
}
/*
- * The only exported function. Returns 1.
+ * It is a constructor, which means that it will automatically be called before
+ * main(). This is GCC-specific but it works at least since 2.95.
+ * Special care must be taken so that it does not need any uninitialized data.
*/
-int select_register(struct poller *p)
+__attribute__((constructor))
+static void _do_register(void)
{
+ struct poller *p;
+
+ if (nbpollers >= MAX_POLLERS)
+ return;
+ p = &pollers[nbpollers++];
+
p->name = "select";
p->pref = 150;
p->private = NULL;
- p->test = select_test;
- p->init = select_init;
- p->term = select_term;
- p->poll = select_poll;
+ p->test = _do_test;
+ p->init = _do_init;
+ p->term = _do_term;
+ p->poll = _do_poll;
p->is_set = __fd_is_set;
p->set = __fd_set;
p->clr = __fd_clr;
p->clo = p->rem = __fd_rem;
p->cond_s = __fd_cond_s;
p->cond_c = __fd_cond_c;
- return 1;
}
int nbpollers = 0;
-/*********************
- * generic functions
- *********************/
-
-extern int select_register(struct poller *p);
-#if defined(ENABLE_POLL)
-extern int poll_register(struct poller *p);
-#endif
-#if defined(ENABLE_EPOLL)
-extern int epoll_register(struct poller *p);
-#endif
-#if defined(ENABLE_KQUEUE)
-extern int kqueue_register(struct poller *p);
-#endif
-
-
/* Deletes an FD from the fdsets, and recomputes the maxfd limit.
* The file descriptor is also closed.
*/
}
-/* registers all known pollers */
-void register_pollers()
-{
- if (select_register(&pollers[nbpollers]))
- nbpollers++;
-#if defined(ENABLE_POLL)
- poll_register(&pollers[nbpollers]);
- nbpollers++;
-#endif
-
-#if defined(ENABLE_EPOLL)
- epoll_register(&pollers[nbpollers]);
- nbpollers++;
-#endif
-
-#if defined(ENABLE_KQUEUE)
- kqueue_register(&pollers[nbpollers]);
- nbpollers++;
-#endif
-}
-
/* disable the specified poller */
void disable_poller(const char *poller_name)
{
fdtab[i].state = FD_STCLOSE;
}
- register_pollers();
- /* Note: we could register external pollers here */
+ /*
+ * Note: we could register external pollers here.
+ * Built-in pollers have been registered before main().
+ */
if (!(cfg_polling_mechanism & POLL_USE_KQUEUE))
disable_poller("kqueue");