blob: 3d7071c9bd9ec2627254329470778a0def5a1180 [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 Tarreau4f60f162007-04-08 16:39:58 +020028struct poller pollers[MAX_POLLERS];
29struct poller cur_poller;
30int nbpollers = 0;
Willy Tarreaubaaee002006-06-26 02:48:02 +020031
32
Willy Tarreau4f60f162007-04-08 16:39:58 +020033/* Deletes an FD from the fdsets, and recomputes the maxfd limit.
34 * The file descriptor is also closed.
35 */
36void fd_delete(int fd)
Willy Tarreaubaaee002006-06-26 02:48:02 +020037{
Willy Tarreau4f60f162007-04-08 16:39:58 +020038 EV_FD_CLO(fd);
39 close(fd);
40 fdtab[fd].state = FD_STCLOSE;
Willy Tarreaubaaee002006-06-26 02:48:02 +020041
Willy Tarreau4f60f162007-04-08 16:39:58 +020042 while ((maxfd-1 >= 0) && (fdtab[maxfd-1].state == FD_STCLOSE))
43 maxfd--;
Willy Tarreaubaaee002006-06-26 02:48:02 +020044}
Willy Tarreaubaaee002006-06-26 02:48:02 +020045
Willy Tarreaubaaee002006-06-26 02:48:02 +020046
Willy Tarreau4f60f162007-04-08 16:39:58 +020047/* disable the specified poller */
48void disable_poller(const char *poller_name)
49{
50 int p;
Willy Tarreaubaaee002006-06-26 02:48:02 +020051
Willy Tarreau4f60f162007-04-08 16:39:58 +020052 for (p = 0; p < nbpollers; p++)
53 if (strcmp(pollers[p].name, poller_name) == 0)
54 pollers[p].pref = 0;
55}
Willy Tarreaubaaee002006-06-26 02:48:02 +020056
57/*
Willy Tarreau4f60f162007-04-08 16:39:58 +020058 * Initialize the pollers till the best one is found.
59 * If none works, returns 0, otherwise 1.
Willy Tarreaubaaee002006-06-26 02:48:02 +020060 */
Willy Tarreau4f60f162007-04-08 16:39:58 +020061int init_pollers()
Willy Tarreaubaaee002006-06-26 02:48:02 +020062{
Willy Tarreau4f60f162007-04-08 16:39:58 +020063 int p;
64 struct poller *bp;
Willy Tarreaubaaee002006-06-26 02:48:02 +020065
Willy Tarreaubaaee002006-06-26 02:48:02 +020066
Willy Tarreau4f60f162007-04-08 16:39:58 +020067 do {
68 bp = NULL;
69 for (p = 0; p < nbpollers; p++)
70 if (!bp || (pollers[p].pref > bp->pref))
71 bp = &pollers[p];
Willy Tarreaubaaee002006-06-26 02:48:02 +020072
Willy Tarreau4f60f162007-04-08 16:39:58 +020073 if (!bp || bp->pref == 0)
Willy Tarreaubaaee002006-06-26 02:48:02 +020074 break;
75
Willy Tarreau4f60f162007-04-08 16:39:58 +020076 if (bp->init(bp)) {
77 memcpy(&cur_poller, bp, sizeof(*bp));
78 return 1;
Willy Tarreaubaaee002006-06-26 02:48:02 +020079 }
Willy Tarreau4f60f162007-04-08 16:39:58 +020080 } while (!bp || bp->pref == 0);
81 return 0;
Willy Tarreaubaaee002006-06-26 02:48:02 +020082}
83
Willy Tarreaubaaee002006-06-26 02:48:02 +020084/*
Krzysztof Piotr Oledzkia643baf2008-05-29 23:53:44 +020085 * Deinitialize the pollers.
86 */
87void deinit_pollers() {
88
89 struct poller *bp;
90 int p;
91
92 for (p = 0; p < nbpollers; p++) {
93 bp = &pollers[p];
94
95 if (bp && bp->pref)
96 bp->term(bp);
97 }
98}
99
100/*
Willy Tarreau2ff76222007-04-09 19:29:56 +0200101 * Lists the known pollers on <out>.
102 * Should be performed only before initialization.
103 */
104int list_pollers(FILE *out)
105{
106 int p;
107 int last, next;
108 int usable;
109 struct poller *bp;
110
111 fprintf(out, "Available polling systems :\n");
112
113 usable = 0;
114 bp = NULL;
115 last = next = -1;
116 while (1) {
117 for (p = 0; p < nbpollers; p++) {
118 if (!bp || (pollers[p].pref > bp->pref))
119 bp = &pollers[p];
120 if ((next < 0 || pollers[p].pref > next)
121 && (last < 0 || pollers[p].pref < last))
122 next = pollers[p].pref;
123 }
124
125 if (next == -1)
126 break;
127
128 for (p = 0; p < nbpollers; p++) {
129 if (pollers[p].pref == next) {
130 fprintf(out, " %10s : ", pollers[p].name);
131 if (pollers[p].pref == 0)
132 fprintf(out, "disabled, ");
133 else
134 fprintf(out, "pref=%3d, ", pollers[p].pref);
135 if (pollers[p].test(&pollers[p])) {
136 fprintf(out, " test result OK");
137 if (next > 0)
138 usable++;
139 } else
140 fprintf(out, " test result FAILED");
141 fprintf(out, "\n");
142 }
143 }
144 last = next;
145 next = -1;
146 };
147 fprintf(out, "Total: %d (%d usable), will use %s.\n", nbpollers, usable, bp ? bp->name : "none");
148 return 0;
149}
150
151/*
152 * Some pollers may lose their connection after a fork(). It may be necessary
153 * to create initialize part of them again. Returns 0 in case of failure,
154 * otherwise 1. The fork() function may be NULL if unused. In case of error,
155 * the the current poller is destroyed and the caller is responsible for trying
156 * another one by calling init_pollers() again.
157 */
158int fork_poller()
159{
160 if (cur_poller.fork) {
161 if (cur_poller.fork(&cur_poller))
162 return 1;
163 cur_poller.term(&cur_poller);
164 return 0;
165 }
166 return 1;
167}
168
169/*
Willy Tarreaubaaee002006-06-26 02:48:02 +0200170 * Local variables:
171 * c-indent-level: 8
172 * c-basic-offset: 8
173 * End:
174 */