]>
git.ipfire.org Git - thirdparty/squid.git/blob - src/fd.cc
3 * DEBUG: section 51 Filedescriptor Functions
4 * AUTHOR: Duane Wessels
6 * SQUID Web Proxy Cache http://www.squid-cache.org/
7 * ----------------------------------------------------------
9 * Squid is the result of efforts by numerous individuals from
10 * the Internet community; see the CONTRIBUTORS file for full
11 * details. Many organizations have provided support for Squid's
12 * development; see the SPONSORS file for full details. Squid is
13 * Copyrighted (C) 2001 by the Regents of the University of
14 * California; see the COPYRIGHT file for full details. Squid
15 * incorporates software developed and/or copyrighted by other
16 * sources; see the CREDITS file for full details.
18 * This program is free software; you can redistribute it and/or modify
19 * it under the terms of the GNU General Public License as published by
20 * the Free Software Foundation; either version 2 of the License, or
21 * (at your option) any later version.
23 * This program is distributed in the hope that it will be useful,
24 * but WITHOUT ANY WARRANTY; without even the implied warranty of
25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26 * GNU General Public License for more details.
28 * You should have received a copy of the GNU General Public License
29 * along with this program; if not, write to the Free Software
30 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111, USA.
35 #include "comm/Loops.h"
40 #include "profiler/Profiler.h"
41 #include "SquidTime.h"
43 // Solaris and possibly others lack MSG_NOSIGNAL optimization
44 // TODO: move this into compat/? Use a dedicated compat file to avoid dragging
45 // sys/types.h and sys/socket.h into the rest of Squid??
47 #define MSG_NOSIGNAL 0
50 int default_read_method(int, char *, int);
51 int default_write_method(int, const char *, int);
53 int socket_read_method(int, char *, int);
54 int socket_write_method(int, const char *, int);
55 int file_read_method(int, char *, int);
56 int file_write_method(int, const char *, int);
58 int msghdr_read_method(int, char *, int);
59 int msghdr_write_method(int, const char *, int);
62 const char *fdTypeStr
[] = {
72 static void fdUpdateBiggest(int fd
, int);
75 fdUpdateBiggest(int fd
, int opening
)
80 assert(fd
< Squid_MaxFD
);
82 if (fd
> Biggest_FD
) {
84 * assert that we are not closing a FD bigger than
85 * our known biggest FD
92 /* if we are here, then fd == Biggest_FD */
94 * assert that we are closing the biggest FD; we can't be
99 while (Biggest_FD
>= 0 && !fd_table
[Biggest_FD
].flags
.open
)
106 fde
*F
= &fd_table
[fd
];
109 assert(F
->flags
.open
);
111 if (F
->type
== FD_FILE
) {
112 assert(F
->read_handler
== NULL
);
113 assert(F
->write_handler
== NULL
);
116 debugs(51, 3, "fd_close FD " << fd
<< " " << F
->desc
);
117 Comm::SetSelect(fd
, COMM_SELECT_READ
, NULL
, NULL
, 0);
118 Comm::SetSelect(fd
, COMM_SELECT_WRITE
, NULL
, NULL
, 0);
119 F
->flags
.open
= false;
120 fdUpdateBiggest(fd
, 0);
128 socket_read_method(int fd
, char *buf
, int len
)
132 i
= recv(fd
, (void *) buf
, len
, 0);
138 file_read_method(int fd
, char *buf
, int len
)
142 i
= _read(fd
, buf
, len
);
148 socket_write_method(int fd
, const char *buf
, int len
)
152 i
= send(fd
, (const void *) buf
, len
, 0);
158 file_write_method(int fd
, const char *buf
, int len
)
162 i
= (_write(fd
, buf
, len
));
169 default_read_method(int fd
, char *buf
, int len
)
173 i
= read(fd
, buf
, len
);
179 default_write_method(int fd
, const char *buf
, int len
)
183 i
= write(fd
, buf
, len
);
189 msghdr_read_method(int fd
, char *buf
, int len
)
192 const int i
= recvmsg(fd
, reinterpret_cast<msghdr
*>(buf
), MSG_DONTWAIT
);
198 msghdr_write_method(int fd
, const char *buf
, int len
)
201 const int i
= sendmsg(fd
, reinterpret_cast<const msghdr
*>(buf
), MSG_NOSIGNAL
);
203 return i
> 0 ? len
: i
; // len is imprecise but the caller expects a match
209 fd_open(int fd
, unsigned int type
, const char *desc
)
216 debugs(51, DBG_IMPORTANT
, "WARNING: Closing open FD " << std::setw(4) << fd
);
220 assert(!F
->flags
.open
);
221 debugs(51, 3, "fd_open() FD " << fd
<< " " << desc
);
223 F
->flags
.open
= true;
227 F
->win32
.handle
= _get_osfhandle(fd
);
234 F
->read_method
= &socket_read_method
;
235 F
->write_method
= &socket_write_method
;
241 F
->read_method
= &file_read_method
;
242 F
->write_method
= &file_write_method
;
246 fatalf("fd_open(): unknown FD type - FD#: %i, type: %u, desc %s\n", fd
, type
, desc
);
253 F
->read_method
= &msghdr_read_method
;
254 F
->write_method
= &msghdr_write_method
;
258 F
->read_method
= &default_read_method
;
259 F
->write_method
= &default_write_method
;
265 fdUpdateBiggest(fd
, 1);
268 xstrncpy(F
->desc
, desc
, FD_DESC_SZ
);
274 fd_note(int fd
, const char *s
)
276 fde
*F
= &fd_table
[fd
];
277 xstrncpy(F
->desc
, s
, FD_DESC_SZ
);
281 fd_bytes(int fd
, int len
, unsigned int type
)
283 fde
*F
= &fd_table
[fd
];
288 assert(type
== FD_READ
|| type
== FD_WRITE
);
291 F
->bytes_read
+= len
;
293 F
->bytes_written
+= len
;
302 for (i
= 0; i
< Squid_MaxFD
; ++i
) {
308 if (i
== fileno(debug_log
))
311 debugs(51, DBG_IMPORTANT
, "Open FD "<< std::left
<< std::setw(10) <<
312 (F
->bytes_read
&& F
->bytes_written
? "READ/WRITE" :
313 F
->bytes_read
? "READING" : F
->bytes_written
? "WRITING" :
315 " "<< std::right
<< std::setw(4) << i
<< " " << F
->desc
);
322 return Squid_MaxFD
- Number_FD
- Opening_FD
;
328 int nrfree
= fdNFree();
330 if (nrfree
< (RESERVED_FD
<< 1))
333 if (nrfree
< (Number_FD
>> 2))
339 /* Called when we runs out of file descriptors */
341 fdAdjustReserved(void)
345 static time_t last
= 0;
347 * don't update too frequently
350 if (last
+ 5 > squid_curtime
)
354 * Calculate a new reserve, based on current usage and a small extra
356 newReserve
= Squid_MaxFD
- Number_FD
+ min(25, Squid_MaxFD
/ 16);
358 if (newReserve
<= RESERVED_FD
)
361 x
= Squid_MaxFD
- 20 - min(25, Squid_MaxFD
/ 16);
363 if (newReserve
> x
) {
364 /* perhaps this should be fatal()? -DW */
365 debugs(51, DBG_CRITICAL
, "WARNING: This machine has a serious shortage of filedescriptors.");
369 if (Squid_MaxFD
- newReserve
< min(256, Squid_MaxFD
/ 2))
370 fatalf("Too few filedescriptors available in the system (%d usable of %d).\n", Squid_MaxFD
- newReserve
, Squid_MaxFD
);
372 debugs(51, DBG_CRITICAL
, "Reserved FD adjusted from " << RESERVED_FD
<< " to " << newReserve
<< " due to failures");
373 RESERVED_FD
= newReserve
;