]> git.ipfire.org Git - thirdparty/squid.git/blob - src/fd.cc
Clean up comm memory on exit
[thirdparty/squid.git] / src / fd.cc
1
2 /*
3 * $Id: fd.cc,v 1.59 2007/09/25 13:24:59 hno Exp $
4 *
5 * DEBUG: section 51 Filedescriptor Functions
6 * AUTHOR: Duane Wessels
7 *
8 * SQUID Web Proxy Cache http://www.squid-cache.org/
9 * ----------------------------------------------------------
10 *
11 * Squid is the result of efforts by numerous individuals from
12 * the Internet community; see the CONTRIBUTORS file for full
13 * details. Many organizations have provided support for Squid's
14 * development; see the SPONSORS file for full details. Squid is
15 * Copyrighted (C) 2001 by the Regents of the University of
16 * California; see the COPYRIGHT file for full details. Squid
17 * incorporates software developed and/or copyrighted by other
18 * sources; see the CREDITS file for full details.
19 *
20 * This program is free software; you can redistribute it and/or modify
21 * it under the terms of the GNU General Public License as published by
22 * the Free Software Foundation; either version 2 of the License, or
23 * (at your option) any later version.
24 *
25 * This program is distributed in the hope that it will be useful,
26 * but WITHOUT ANY WARRANTY; without even the implied warranty of
27 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
28 * GNU General Public License for more details.
29 *
30 * You should have received a copy of the GNU General Public License
31 * along with this program; if not, write to the Free Software
32 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
33 *
34 */
35
36 #include "squid.h"
37 #include "fde.h"
38 #include "SquidTime.h"
39
40 int default_read_method(int, char *, int);
41 int default_write_method(int, const char *, int);
42 #ifdef _SQUID_MSWIN_
43 int socket_read_method(int, char *, int);
44 int socket_write_method(int, const char *, int);
45 int file_read_method(int, char *, int);
46 int file_write_method(int, const char *, int);
47 #endif
48
49 const char *fdTypeStr[] =
50 {
51 "None",
52 "Log",
53 "File",
54 "Socket",
55 "Pipe",
56 "Unknown"
57 };
58
59 static void fdUpdateBiggest(int fd, int);
60
61 static void
62 fdUpdateBiggest(int fd, int opening)
63 {
64 if (fd < Biggest_FD)
65 return;
66
67 assert(fd < Squid_MaxFD);
68
69 if (fd > Biggest_FD) {
70 /*
71 * assert that we are not closing a FD bigger than
72 * our known biggest FD
73 */
74 assert(opening);
75 Biggest_FD = fd;
76 return;
77 }
78
79 /* if we are here, then fd == Biggest_FD */
80 /*
81 * assert that we are closing the biggest FD; we can't be
82 * re-opening it
83 */
84 assert(!opening);
85
86 while (Biggest_FD >= 0 && !fd_table[Biggest_FD].flags.open)
87 Biggest_FD--;
88 }
89
90 void
91 fd_close(int fd)
92 {
93 fde *F = &fd_table[fd];
94
95 if (F->type == FD_FILE) {
96 assert(F->read_handler == NULL);
97 assert(F->write_handler == NULL);
98 }
99
100 debugs(51, 3, "fd_close FD " << fd << " " << F->desc);
101 commSetSelect(fd, COMM_SELECT_READ, NULL, NULL, 0);
102 commSetSelect(fd, COMM_SELECT_WRITE, NULL, NULL, 0);
103 F->flags.open = 0;
104 fdUpdateBiggest(fd, 0);
105 Number_FD--;
106 memset(F, '\0', sizeof(fde));
107 F->timeout = 0;
108 }
109
110 #ifdef _SQUID_MSWIN_
111
112 int
113 socket_read_method(int fd, char *buf, int len)
114 {
115 int i;
116 PROF_start(send);
117 i = recv(fd, (void *) buf, len, 0);
118 PROF_stop(send);
119 return i;
120 }
121
122 int
123 file_read_method(int fd, char *buf, int len)
124 {
125 int i;
126 PROF_start(read);
127 i = _read(fd, buf, len);
128 PROF_stop(read);
129 return i;
130 }
131
132 int
133 socket_write_method(int fd, const char *buf, int len)
134 {
135 int i;
136 PROF_start(send);
137 i = send(fd, (const void *) buf, len, 0);
138 PROF_stop(send);
139 return i;
140 }
141
142 int
143 file_write_method(int fd, const char *buf, int len)
144 {
145 return (_write(fd, buf, len));
146 }
147
148 #else
149 int
150 default_read_method(int fd, char *buf, int len)
151 {
152 int i;
153 PROF_start(read);
154 i = read(fd, buf, len);
155 PROF_stop(read);
156 return i;
157 }
158
159 int
160 default_write_method(int fd, const char *buf, int len)
161 {
162 int i;
163 PROF_start(write);
164 i = write(fd, buf, len);
165 PROF_stop(write);
166 return i;
167 }
168
169 #endif
170
171 void
172 fd_open(int fd, unsigned int type, const char *desc)
173 {
174 fde *F;
175 assert(fd >= 0);
176 F = &fd_table[fd];
177
178 if (F->flags.open) {
179 debugs(51, 1, "WARNING: Closing open FD " << std::setw(4) << fd);
180 fd_close(fd);
181 }
182
183 assert(!F->flags.open);
184 debugs(51, 3, "fd_open FD " << fd << " " << desc);
185 F->type = type;
186 F->flags.open = 1;
187 F->epoll_state = 0;
188 #ifdef _SQUID_MSWIN_
189
190 F->win32.handle = _get_osfhandle(fd);
191
192 switch (type) {
193
194 case FD_SOCKET:
195
196 case FD_PIPE:
197 F->read_method = &socket_read_method;
198 F->write_method = &socket_write_method;
199 break;
200
201 case FD_FILE:
202
203 case FD_LOG:
204 F->read_method = &file_read_method;
205 F->write_method = &file_write_method;
206 break;
207
208 default:
209 fatalf("fd_open(): unknown FD type - FD#: %i, type: %u, desc %s\n", fd, type, desc);
210 }
211
212 #else
213 F->read_method = &default_read_method;
214
215 F->write_method = &default_write_method;
216
217 #endif
218
219 fdUpdateBiggest(fd, 1);
220
221 if (desc)
222 xstrncpy(F->desc, desc, FD_DESC_SZ);
223
224 Number_FD++;
225 }
226
227 void
228 fd_note(int fd, const char *s)
229 {
230 fde *F = &fd_table[fd];
231 xstrncpy(F->desc, s, FD_DESC_SZ);
232 }
233
234 void
235 fd_bytes(int fd, int len, unsigned int type)
236 {
237 fde *F = &fd_table[fd];
238
239 if (len < 0)
240 return;
241
242 assert(type == FD_READ || type == FD_WRITE);
243
244 if (type == FD_READ)
245 F->bytes_read += len;
246 else
247 F->bytes_written += len;
248 }
249
250 void
251 fdDumpOpen(void)
252 {
253 int i;
254 fde *F;
255
256 for (i = 0; i < Squid_MaxFD; i++) {
257 F = &fd_table[i];
258
259 if (!F->flags.open)
260 continue;
261
262 if (i == fileno(debug_log))
263 continue;
264
265 debugs(51, 1, "Open FD "<< std::left<< std::setw(10) <<
266 (F->bytes_read && F->bytes_written ? "READ/WRITE" :
267 F->bytes_read ? "READING" : F->bytes_written ? "WRITING" :
268 null_string) <<
269 " "<< std::right << std::setw(4) << i << " " << F->desc);
270 }
271 }
272
273 int
274 fdNFree(void)
275 {
276 return Squid_MaxFD - Number_FD - Opening_FD;
277 }
278
279 int
280 fdUsageHigh(void)
281 {
282 int nrfree = fdNFree();
283
284 if (nrfree < (RESERVED_FD << 1))
285 return 1;
286
287 if (nrfree < (Number_FD >> 2))
288 return 1;
289
290 return 0;
291 }
292
293 /* Called when we runs out of file descriptors */
294 void
295 fdAdjustReserved(void)
296 {
297 int newReserve;
298 int x;
299 static time_t last = 0;
300 /*
301 * don't update too frequently
302 */
303
304 if (last + 5 > squid_curtime)
305 return;
306
307 /*
308 * Calculate a new reserve, based on current usage and a small extra
309 */
310 newReserve = Squid_MaxFD - Number_FD + XMIN(25, Squid_MaxFD / 16);
311
312 if (newReserve <= RESERVED_FD)
313 return;
314
315 x = Squid_MaxFD - 20 - XMIN(25, Squid_MaxFD / 16);
316
317 if (newReserve > x) {
318 /* perhaps this should be fatal()? -DW */
319 debugs(51, 0, "WARNING: This machine has a serious shortage of filedescriptors.");
320 newReserve = x;
321 }
322
323 if (Squid_MaxFD - newReserve < XMIN(256, Squid_MaxFD / 2))
324 fatalf("Too few filedescriptors available in the system (%d usable of %d).\n", Squid_MaxFD - newReserve, Squid_MaxFD);
325
326 debugs(51, 0, "Reserved FD adjusted from " << RESERVED_FD << " to " << newReserve << " due to failures");
327 RESERVED_FD = newReserve;
328 }