blob: daa347f31d467a15895bb675e824921a2bb151a0 [file] [log] [blame]
Willy Tarreaubaaee002006-06-26 02:48:02 +02001/*
2 * File descriptors management functions.
3 *
Willy Tarreauec6c5df2008-07-15 00:22:45 +02004 * Copyright 2000-2008 Willy Tarreau <w@1wt.eu>
Willy Tarreaubaaee002006-06-26 02:48:02 +02005 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 *
11 */
12
Willy Tarreau2ff76222007-04-09 19:29:56 +020013#include <stdio.h>
Willy Tarreau4f60f162007-04-08 16:39:58 +020014#include <string.h>
Willy Tarreaubaaee002006-06-26 02:48:02 +020015#include <unistd.h>
Willy Tarreaubaaee002006-06-26 02:48:02 +020016#include <sys/types.h>
17
Willy Tarreau2dd0d472006-06-29 17:53:05 +020018#include <common/compat.h>
19#include <common/config.h>
Willy Tarreaubaaee002006-06-26 02:48:02 +020020
Willy Tarreau2a429502006-10-15 14:52:29 +020021#include <proto/fd.h>
Willy Tarreaubaaee002006-06-26 02:48:02 +020022
23struct fdtab *fdtab = NULL; /* array of all the file descriptors */
24int maxfd; /* # of the highest fd + 1 */
25int totalconn; /* total # of terminated sessions */
26int actconn; /* # of active sessions */
27
Willy Tarreaubaaee002006-06-26 02:48:02 +020028int cfg_polling_mechanism = 0; /* POLL_USE_{SELECT|POLL|EPOLL} */
29
Willy Tarreau4f60f162007-04-08 16:39:58 +020030struct poller pollers[MAX_POLLERS];
31struct poller cur_poller;
32int nbpollers = 0;
Willy Tarreaubaaee002006-06-26 02:48:02 +020033
34
Willy Tarreau4f60f162007-04-08 16:39:58 +020035/* Deletes an FD from the fdsets, and recomputes the maxfd limit.
36 * The file descriptor is also closed.
37 */
38void fd_delete(int fd)
Willy Tarreaubaaee002006-06-26 02:48:02 +020039{
Willy Tarreau4f60f162007-04-08 16:39:58 +020040 EV_FD_CLO(fd);
41 close(fd);
42 fdtab[fd].state = FD_STCLOSE;
Willy Tarreaubaaee002006-06-26 02:48:02 +020043
Willy Tarreau4f60f162007-04-08 16:39:58 +020044 while ((maxfd-1 >= 0) && (fdtab[maxfd-1].state == FD_STCLOSE))
45 maxfd--;
Willy Tarreaubaaee002006-06-26 02:48:02 +020046}
Willy Tarreaubaaee002006-06-26 02:48:02 +020047
Willy Tarreaubaaee002006-06-26 02:48:02 +020048
Willy Tarreau4f60f162007-04-08 16:39:58 +020049/* disable the specified poller */
50void disable_poller(const char *poller_name)
51{
52 int p;
Willy Tarreaubaaee002006-06-26 02:48:02 +020053
Willy Tarreau4f60f162007-04-08 16:39:58 +020054 for (p = 0; p < nbpollers; p++)
55 if (strcmp(pollers[p].name, poller_name) == 0)
56 pollers[p].pref = 0;
57}
Willy Tarreaubaaee002006-06-26 02:48:02 +020058
59/*
Willy Tarreau4f60f162007-04-08 16:39:58 +020060 * Initialize the pollers till the best one is found.
61 * If none works, returns 0, otherwise 1.
Willy Tarreaubaaee002006-06-26 02:48:02 +020062 */
Willy Tarreau4f60f162007-04-08 16:39:58 +020063int init_pollers()
Willy Tarreaubaaee002006-06-26 02:48:02 +020064{
Willy Tarreau4f60f162007-04-08 16:39:58 +020065 int p;
66 struct poller *bp;
Willy Tarreaubaaee002006-06-26 02:48:02 +020067
Willy Tarreaubaaee002006-06-26 02:48:02 +020068
Willy Tarreau4f60f162007-04-08 16:39:58 +020069 do {
70 bp = NULL;
71 for (p = 0; p < nbpollers; p++)
72 if (!bp || (pollers[p].pref > bp->pref))
73 bp = &pollers[p];
Willy Tarreaubaaee002006-06-26 02:48:02 +020074
Willy Tarreau4f60f162007-04-08 16:39:58 +020075 if (!bp || bp->pref == 0)
Willy Tarreaubaaee002006-06-26 02:48:02 +020076 break;
77
Willy Tarreau4f60f162007-04-08 16:39:58 +020078 if (bp->init(bp)) {
79 memcpy(&cur_poller, bp, sizeof(*bp));
80 return 1;
Willy Tarreaubaaee002006-06-26 02:48:02 +020081 }
Willy Tarreau4f60f162007-04-08 16:39:58 +020082 } while (!bp || bp->pref == 0);
83 return 0;
Willy Tarreaubaaee002006-06-26 02:48:02 +020084}
85
Willy Tarreaubaaee002006-06-26 02:48:02 +020086/*
Krzysztof Piotr Oledzkia643baf2008-05-29 23:53:44 +020087 * Deinitialize the pollers.
88 */
89void deinit_pollers() {
90
91 struct poller *bp;
92 int p;
93
94 for (p = 0; p < nbpollers; p++) {
95 bp = &pollers[p];
96
97 if (bp && bp->pref)
98 bp->term(bp);
99 }
100}
101
102/*
Willy Tarreau2ff76222007-04-09 19:29:56 +0200103 * Lists the known pollers on <out>.
104 * Should be performed only before initialization.
105 */
106int list_pollers(FILE *out)
107{
108 int p;
109 int last, next;
110 int usable;
111 struct poller *bp;
112
113 fprintf(out, "Available polling systems :\n");
114
115 usable = 0;
116 bp = NULL;
117 last = next = -1;
118 while (1) {
119 for (p = 0; p < nbpollers; p++) {
120 if (!bp || (pollers[p].pref > bp->pref))
121 bp = &pollers[p];
122 if ((next < 0 || pollers[p].pref > next)
123 && (last < 0 || pollers[p].pref < last))
124 next = pollers[p].pref;
125 }
126
127 if (next == -1)
128 break;
129
130 for (p = 0; p < nbpollers; p++) {
131 if (pollers[p].pref == next) {
132 fprintf(out, " %10s : ", pollers[p].name);
133 if (pollers[p].pref == 0)
134 fprintf(out, "disabled, ");
135 else
136 fprintf(out, "pref=%3d, ", pollers[p].pref);
137 if (pollers[p].test(&pollers[p])) {
138 fprintf(out, " test result OK");
139 if (next > 0)
140 usable++;
141 } else
142 fprintf(out, " test result FAILED");
143 fprintf(out, "\n");
144 }
145 }
146 last = next;
147 next = -1;
148 };
149 fprintf(out, "Total: %d (%d usable), will use %s.\n", nbpollers, usable, bp ? bp->name : "none");
150 return 0;
151}
152
153/*
154 * Some pollers may lose their connection after a fork(). It may be necessary
155 * to create initialize part of them again. Returns 0 in case of failure,
156 * otherwise 1. The fork() function may be NULL if unused. In case of error,
157 * the the current poller is destroyed and the caller is responsible for trying
158 * another one by calling init_pollers() again.
159 */
160int fork_poller()
161{
162 if (cur_poller.fork) {
163 if (cur_poller.fork(&cur_poller))
164 return 1;
165 cur_poller.term(&cur_poller);
166 return 0;
167 }
168 return 1;
169}
170
171/*
Willy Tarreaubaaee002006-06-26 02:48:02 +0200172 * Local variables:
173 * c-indent-level: 8
174 * c-basic-offset: 8
175 * End:
176 */