blob: 80bddd6a0f78863801d7f02f49e2bb6d4ded9a84 [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 Tarreauc6f4ce82009-06-10 11:09:37 +020022#include <proto/port_range.h>
Willy Tarreaubaaee002006-06-26 02:48:02 +020023
24struct fdtab *fdtab = NULL; /* array of all the file descriptors */
Willy Tarreau8d5d77e2009-10-18 07:25:52 +020025struct fdinfo *fdinfo = NULL; /* less-often used infos for file descriptors */
Willy Tarreaubaaee002006-06-26 02:48:02 +020026int maxfd; /* # of the highest fd + 1 */
27int totalconn; /* total # of terminated sessions */
28int actconn; /* # of active sessions */
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);
Willy Tarreau8d5d77e2009-10-18 07:25:52 +020041 port_range_release_port(fdinfo[fd].port_range, fdinfo[fd].local_port);
42 fdinfo[fd].port_range = NULL;
Willy Tarreau4f60f162007-04-08 16:39:58 +020043 close(fd);
44 fdtab[fd].state = FD_STCLOSE;
Willy Tarreaubaaee002006-06-26 02:48:02 +020045
Willy Tarreau4f60f162007-04-08 16:39:58 +020046 while ((maxfd-1 >= 0) && (fdtab[maxfd-1].state == FD_STCLOSE))
47 maxfd--;
Willy Tarreaubaaee002006-06-26 02:48:02 +020048}
Willy Tarreaubaaee002006-06-26 02:48:02 +020049
Willy Tarreaubaaee002006-06-26 02:48:02 +020050
Willy Tarreau4f60f162007-04-08 16:39:58 +020051/* disable the specified poller */
52void disable_poller(const char *poller_name)
53{
54 int p;
Willy Tarreaubaaee002006-06-26 02:48:02 +020055
Willy Tarreau4f60f162007-04-08 16:39:58 +020056 for (p = 0; p < nbpollers; p++)
57 if (strcmp(pollers[p].name, poller_name) == 0)
58 pollers[p].pref = 0;
59}
Willy Tarreaubaaee002006-06-26 02:48:02 +020060
61/*
Willy Tarreau4f60f162007-04-08 16:39:58 +020062 * Initialize the pollers till the best one is found.
63 * If none works, returns 0, otherwise 1.
Willy Tarreaubaaee002006-06-26 02:48:02 +020064 */
Willy Tarreau4f60f162007-04-08 16:39:58 +020065int init_pollers()
Willy Tarreaubaaee002006-06-26 02:48:02 +020066{
Willy Tarreau4f60f162007-04-08 16:39:58 +020067 int p;
68 struct poller *bp;
Willy Tarreaubaaee002006-06-26 02:48:02 +020069
Willy Tarreaubaaee002006-06-26 02:48:02 +020070
Willy Tarreau4f60f162007-04-08 16:39:58 +020071 do {
72 bp = NULL;
73 for (p = 0; p < nbpollers; p++)
74 if (!bp || (pollers[p].pref > bp->pref))
75 bp = &pollers[p];
Willy Tarreaubaaee002006-06-26 02:48:02 +020076
Willy Tarreau4f60f162007-04-08 16:39:58 +020077 if (!bp || bp->pref == 0)
Willy Tarreaubaaee002006-06-26 02:48:02 +020078 break;
79
Willy Tarreau4f60f162007-04-08 16:39:58 +020080 if (bp->init(bp)) {
81 memcpy(&cur_poller, bp, sizeof(*bp));
82 return 1;
Willy Tarreaubaaee002006-06-26 02:48:02 +020083 }
Willy Tarreau4f60f162007-04-08 16:39:58 +020084 } while (!bp || bp->pref == 0);
85 return 0;
Willy Tarreaubaaee002006-06-26 02:48:02 +020086}
87
Willy Tarreaubaaee002006-06-26 02:48:02 +020088/*
Krzysztof Piotr Oledzkia643baf2008-05-29 23:53:44 +020089 * Deinitialize the pollers.
90 */
91void deinit_pollers() {
92
93 struct poller *bp;
94 int p;
95
96 for (p = 0; p < nbpollers; p++) {
97 bp = &pollers[p];
98
99 if (bp && bp->pref)
100 bp->term(bp);
101 }
102}
103
104/*
Willy Tarreau2ff76222007-04-09 19:29:56 +0200105 * Lists the known pollers on <out>.
106 * Should be performed only before initialization.
107 */
108int list_pollers(FILE *out)
109{
110 int p;
111 int last, next;
112 int usable;
113 struct poller *bp;
114
115 fprintf(out, "Available polling systems :\n");
116
117 usable = 0;
118 bp = NULL;
119 last = next = -1;
120 while (1) {
121 for (p = 0; p < nbpollers; p++) {
Willy Tarreau2ff76222007-04-09 19:29:56 +0200122 if ((next < 0 || pollers[p].pref > next)
Willy Tarreaue79c3b22010-11-19 10:20:36 +0100123 && (last < 0 || pollers[p].pref < last)) {
Willy Tarreau2ff76222007-04-09 19:29:56 +0200124 next = pollers[p].pref;
Willy Tarreaue79c3b22010-11-19 10:20:36 +0100125 if (!bp || (pollers[p].pref > bp->pref))
126 bp = &pollers[p];
127 }
Willy Tarreau2ff76222007-04-09 19:29:56 +0200128 }
129
130 if (next == -1)
131 break;
132
133 for (p = 0; p < nbpollers; p++) {
134 if (pollers[p].pref == next) {
135 fprintf(out, " %10s : ", pollers[p].name);
136 if (pollers[p].pref == 0)
137 fprintf(out, "disabled, ");
138 else
139 fprintf(out, "pref=%3d, ", pollers[p].pref);
140 if (pollers[p].test(&pollers[p])) {
141 fprintf(out, " test result OK");
142 if (next > 0)
143 usable++;
Willy Tarreaue79c3b22010-11-19 10:20:36 +0100144 } else {
Willy Tarreau2ff76222007-04-09 19:29:56 +0200145 fprintf(out, " test result FAILED");
Willy Tarreaue79c3b22010-11-19 10:20:36 +0100146 if (bp == &pollers[p])
147 bp = NULL;
148 }
Willy Tarreau2ff76222007-04-09 19:29:56 +0200149 fprintf(out, "\n");
150 }
151 }
152 last = next;
153 next = -1;
154 };
155 fprintf(out, "Total: %d (%d usable), will use %s.\n", nbpollers, usable, bp ? bp->name : "none");
156 return 0;
157}
158
159/*
160 * Some pollers may lose their connection after a fork(). It may be necessary
161 * to create initialize part of them again. Returns 0 in case of failure,
162 * otherwise 1. The fork() function may be NULL if unused. In case of error,
163 * the the current poller is destroyed and the caller is responsible for trying
164 * another one by calling init_pollers() again.
165 */
166int fork_poller()
167{
168 if (cur_poller.fork) {
169 if (cur_poller.fork(&cur_poller))
170 return 1;
171 cur_poller.term(&cur_poller);
172 return 0;
173 }
174 return 1;
175}
176
177/*
Willy Tarreaubaaee002006-06-26 02:48:02 +0200178 * Local variables:
179 * c-indent-level: 8
180 * c-basic-offset: 8
181 * End:
182 */