]>
git.ipfire.org Git - thirdparty/squid.git/blob - src/fd.cc
2 * Copyright (C) 1996-2014 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"
18 #include "profiler/Profiler.h"
19 #include "SquidTime.h"
21 // Solaris and possibly others lack MSG_NOSIGNAL optimization
22 // TODO: move this into compat/? Use a dedicated compat file to avoid dragging
23 // sys/socket.h into the rest of Squid??
25 #define MSG_NOSIGNAL 0
28 int default_read_method(int, char *, int);
29 int default_write_method(int, const char *, int);
31 int socket_read_method(int, char *, int);
32 int socket_write_method(int, const char *, int);
33 int file_read_method(int, char *, int);
34 int file_write_method(int, const char *, int);
36 int msghdr_read_method(int, char *, int);
37 int msghdr_write_method(int, const char *, int);
40 const char *fdTypeStr
[] = {
50 static void fdUpdateBiggest(int fd
, int);
53 fdUpdateBiggest(int fd
, int opening
)
58 assert(fd
< Squid_MaxFD
);
60 if (fd
> Biggest_FD
) {
62 * assert that we are not closing a FD bigger than
63 * our known biggest FD
70 /* if we are here, then fd == Biggest_FD */
72 * assert that we are closing the biggest FD; we can't be
77 while (Biggest_FD
>= 0 && !fd_table
[Biggest_FD
].flags
.open
)
84 fde
*F
= &fd_table
[fd
];
87 assert(F
->flags
.open
);
89 if (F
->type
== FD_FILE
) {
90 assert(F
->read_handler
== NULL
);
91 assert(F
->write_handler
== NULL
);
94 debugs(51, 3, "fd_close FD " << fd
<< " " << F
->desc
);
95 Comm::SetSelect(fd
, COMM_SELECT_READ
, NULL
, NULL
, 0);
96 Comm::SetSelect(fd
, COMM_SELECT_WRITE
, NULL
, NULL
, 0);
97 F
->flags
.open
= false;
98 fdUpdateBiggest(fd
, 0);
106 socket_read_method(int fd
, char *buf
, int len
)
110 i
= recv(fd
, (void *) buf
, len
, 0);
116 file_read_method(int fd
, char *buf
, int len
)
120 i
= _read(fd
, buf
, len
);
126 socket_write_method(int fd
, const char *buf
, int len
)
130 i
= send(fd
, (const void *) buf
, len
, 0);
136 file_write_method(int fd
, const char *buf
, int len
)
140 i
= (_write(fd
, buf
, len
));
147 default_read_method(int fd
, char *buf
, int len
)
151 i
= read(fd
, buf
, len
);
157 default_write_method(int fd
, const char *buf
, int len
)
161 i
= write(fd
, buf
, len
);
167 msghdr_read_method(int fd
, char *buf
, int)
170 const int i
= recvmsg(fd
, reinterpret_cast<msghdr
*>(buf
), MSG_DONTWAIT
);
176 msghdr_write_method(int fd
, const char *buf
, int len
)
179 const int i
= sendmsg(fd
, reinterpret_cast<const msghdr
*>(buf
), MSG_NOSIGNAL
);
181 return i
> 0 ? len
: i
; // len is imprecise but the caller expects a match
187 fd_open(int fd
, unsigned int type
, const char *desc
)
194 debugs(51, DBG_IMPORTANT
, "WARNING: Closing open FD " << std::setw(4) << fd
);
198 assert(!F
->flags
.open
);
199 debugs(51, 3, "fd_open() FD " << fd
<< " " << desc
);
201 F
->flags
.open
= true;
205 F
->win32
.handle
= _get_osfhandle(fd
);
212 F
->read_method
= &socket_read_method
;
213 F
->write_method
= &socket_write_method
;
219 F
->read_method
= &file_read_method
;
220 F
->write_method
= &file_write_method
;
224 fatalf("fd_open(): unknown FD type - FD#: %i, type: %u, desc %s\n", fd
, type
, desc
);
231 F
->read_method
= &msghdr_read_method
;
232 F
->write_method
= &msghdr_write_method
;
236 F
->read_method
= &default_read_method
;
237 F
->write_method
= &default_write_method
;
243 fdUpdateBiggest(fd
, 1);
246 xstrncpy(F
->desc
, desc
, FD_DESC_SZ
);
252 fd_note(int fd
, const char *s
)
254 fde
*F
= &fd_table
[fd
];
255 xstrncpy(F
->desc
, s
, FD_DESC_SZ
);
259 fd_bytes(int fd
, int len
, unsigned int type
)
261 fde
*F
= &fd_table
[fd
];
266 assert(type
== FD_READ
|| type
== FD_WRITE
);
269 F
->bytes_read
+= len
;
271 F
->bytes_written
+= len
;
280 for (i
= 0; i
< Squid_MaxFD
; ++i
) {
286 if (i
== fileno(debug_log
))
289 debugs(51, DBG_IMPORTANT
, "Open FD "<< std::left
<< std::setw(10) <<
290 (F
->bytes_read
&& F
->bytes_written
? "READ/WRITE" :
291 F
->bytes_read
? "READING" : F
->bytes_written
? "WRITING" :
293 " "<< std::right
<< std::setw(4) << i
<< " " << F
->desc
);
300 return Squid_MaxFD
- Number_FD
- Opening_FD
;
306 int nrfree
= fdNFree();
308 if (nrfree
< (RESERVED_FD
<< 1))
311 if (nrfree
< (Number_FD
>> 2))
317 /* Called when we runs out of file descriptors */
319 fdAdjustReserved(void)
323 static time_t last
= 0;
325 * don't update too frequently
328 if (last
+ 5 > squid_curtime
)
332 * Calculate a new reserve, based on current usage and a small extra
334 newReserve
= Squid_MaxFD
- Number_FD
+ min(25, Squid_MaxFD
/ 16);
336 if (newReserve
<= RESERVED_FD
)
339 x
= Squid_MaxFD
- 20 - min(25, Squid_MaxFD
/ 16);
341 if (newReserve
> x
) {
342 /* perhaps this should be fatal()? -DW */
343 debugs(51, DBG_CRITICAL
, "WARNING: This machine has a serious shortage of filedescriptors.");
347 if (Squid_MaxFD
- newReserve
< min(256, Squid_MaxFD
/ 2))
348 fatalf("Too few filedescriptors available in the system (%d usable of %d).\n", Squid_MaxFD
- newReserve
, Squid_MaxFD
);
350 debugs(51, DBG_CRITICAL
, "Reserved FD adjusted from " << RESERVED_FD
<< " to " << newReserve
<<
351 " due to failures (" << (Squid_MaxFD
- newReserve
) << "/" << Squid_MaxFD
<< " file descriptors available)");
352 RESERVED_FD
= newReserve
;