]>
git.ipfire.org Git - thirdparty/squid.git/blob - src/fd.cc
2 * Copyright (C) 1996-2023 The Squid Software Foundation and contributors
4 * Squid software is distributed under GPLv2+ license and includes
5 * contributions from numerous individuals and organizations.
6 * Please see the COPYING and CONTRIBUTORS files for details.
9 /* DEBUG: section 51 Filedescriptor Functions */
12 #include "comm/Loops.h"
13 #include "debug/Messages.h"
14 #include "debug/Stream.h"
20 // Solaris and possibly others lack MSG_NOSIGNAL optimization
21 // TODO: move this into compat/? Use a dedicated compat file to avoid dragging
22 // sys/socket.h into the rest of Squid??
24 #define MSG_NOSIGNAL 0
27 int default_read_method(int, char *, int);
28 int default_write_method(int, const char *, int);
30 int socket_read_method(int, char *, int);
31 int socket_write_method(int, const char *, int);
32 int file_read_method(int, char *, int);
33 int file_write_method(int, const char *, int);
35 int msghdr_read_method(int, char *, int);
36 int msghdr_write_method(int, const char *, int);
39 const char *fdTypeStr
[] = {
49 static void fdUpdateBiggest(int fd
, int);
52 fdUpdateBiggest(int fd
, int opening
)
57 assert(fd
< Squid_MaxFD
);
59 if (fd
> Biggest_FD
) {
61 * assert that we are not closing a FD bigger than
62 * our known biggest FD
69 /* if we are here, then fd == Biggest_FD */
71 * assert that we are closing the biggest FD; we can't be
76 while (Biggest_FD
>= 0 && !fd_table
[Biggest_FD
].flags
.open
)
83 fde
*F
= &fd_table
[fd
];
86 assert(F
->flags
.open
);
88 if (F
->type
== FD_FILE
) {
89 assert(F
->read_handler
== nullptr);
90 assert(F
->write_handler
== nullptr);
93 debugs(51, 3, "fd_close FD " << fd
<< " " << F
->desc
);
94 Comm::ResetSelect(fd
);
95 F
->flags
.open
= false;
96 fdUpdateBiggest(fd
, 0);
104 socket_read_method(int fd
, char *buf
, int len
)
106 return recv(fd
, (void *) buf
, len
, 0);
110 file_read_method(int fd
, char *buf
, int len
)
112 return _read(fd
, buf
, len
);
116 socket_write_method(int fd
, const char *buf
, int len
)
118 return send(fd
, (const void *) buf
, len
, 0);
122 file_write_method(int fd
, const char *buf
, int len
)
124 return _write(fd
, buf
, len
);
129 default_read_method(int fd
, char *buf
, int len
)
131 return read(fd
, buf
, len
);
135 default_write_method(int fd
, const char *buf
, int len
)
137 return write(fd
, buf
, len
);
141 msghdr_read_method(int fd
, char *buf
, int)
143 return recvmsg(fd
, reinterpret_cast<msghdr
*>(buf
), MSG_DONTWAIT
);
147 msghdr_write_method(int fd
, const char *buf
, int len
)
149 const int i
= sendmsg(fd
, reinterpret_cast<const msghdr
*>(buf
), MSG_NOSIGNAL
);
150 return i
> 0 ? len
: i
; // len is imprecise but the caller expects a match
156 fd_open(int fd
, unsigned int type
, const char *desc
)
163 debugs(51, DBG_IMPORTANT
, "WARNING: Closing open FD " << std::setw(4) << fd
);
167 assert(!F
->flags
.open
);
168 debugs(51, 3, "fd_open() FD " << fd
<< " " << desc
);
170 F
->flags
.open
= true;
174 F
->win32
.handle
= _get_osfhandle(fd
);
181 F
->setIo(&socket_read_method
, &socket_write_method
);
187 F
->setIo(&file_read_method
, &file_write_method
);
191 fatalf("fd_open(): unknown FD type - FD#: %i, type: %u, desc %s\n", fd
, type
, desc
);
198 F
->setIo(&msghdr_read_method
, &msghdr_write_method
);
202 F
->setIo(&default_read_method
, &default_write_method
);
208 fdUpdateBiggest(fd
, 1);
216 fd_note(int fd
, const char *s
)
218 fde
*F
= &fd_table
[fd
];
220 xstrncpy(F
->desc
, s
, FD_DESC_SZ
);
222 *(F
->desc
) = 0; // ""-string
226 fd_bytes(int fd
, int len
, unsigned int type
)
228 fde
*F
= &fd_table
[fd
];
233 assert(type
== FD_READ
|| type
== FD_WRITE
);
236 F
->bytes_read
+= len
;
238 F
->bytes_written
+= len
;
247 for (i
= 0; i
< Squid_MaxFD
; ++i
) {
253 if (i
== fileno(debug_log
))
256 debugs(51, Important(17), "Open FD "<< std::left
<< std::setw(10) <<
257 (F
->bytes_read
&& F
->bytes_written
? "READ/WRITE" :
258 F
->bytes_read
? "READING" : F
->bytes_written
? "WRITING" :
260 " "<< std::right
<< std::setw(4) << i
<< " " << F
->desc
);
267 return Squid_MaxFD
- Number_FD
- Opening_FD
;
273 int nrfree
= fdNFree();
275 if (nrfree
< (RESERVED_FD
<< 1))
278 if (nrfree
< (Number_FD
>> 2))
284 /* Called when we runs out of file descriptors */
286 fdAdjustReserved(void)
290 static time_t last
= 0;
292 * don't update too frequently
295 if (last
+ 5 > squid_curtime
)
299 * Calculate a new reserve, based on current usage and a small extra
301 newReserve
= Squid_MaxFD
- Number_FD
+ min(25, Squid_MaxFD
/ 16);
303 if (newReserve
<= RESERVED_FD
)
306 x
= Squid_MaxFD
- 20 - min(25, Squid_MaxFD
/ 16);
308 if (newReserve
> x
) {
309 /* perhaps this should be fatal()? -DW */
310 debugs(51, DBG_CRITICAL
, "WARNING: This machine has a serious shortage of filedescriptors.");
314 if (Squid_MaxFD
- newReserve
< min(256, Squid_MaxFD
/ 2))
315 fatalf("Too few filedescriptors available in the system (%d usable of %d).\n", Squid_MaxFD
- newReserve
, Squid_MaxFD
);
317 debugs(51, DBG_CRITICAL
, "Reserved FD adjusted from " << RESERVED_FD
<< " to " << newReserve
<<
318 " due to failures (" << (Squid_MaxFD
- newReserve
) << "/" << Squid_MaxFD
<< " file descriptors available)");
319 RESERVED_FD
= newReserve
;