mirror of
https://github.com/3proxy/3proxy.git
synced 2026-11-05 09:25:49 +08:00
Event loops: served on by default, the data relayed by the loops
loopmode is cb unless a configuration says otherwise, as -L2 had it for a service: its clients on event loops, a connection's data relayed by the loop itself where nothing but the sockets is between its sides. A service whose clients cannot share a thread (threadperclient: PAM, LDAP, FilePlugin, names resolved by the system, -ne) or listening for connections back (-R) still gives each a thread, as do the standalone services and builds without fibers. loopmode on and -L keep the loops with the relay on the client's stack; loopmode off and -L0 a thread for each client. The man page tells of cb. tests/run.py --loopmode takes the mode (cb, on, off) to give every configuration, with two loops; the Linux workflow runs the suite once more with a thread for each client, which is no longer what a configuration gets by default. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
143158e97f
commit
023eb8f830
2
.github/workflows/c-cpp-Linux.yml
vendored
2
.github/workflows/c-cpp-Linux.yml
vendored
@ -30,6 +30,8 @@ jobs:
|
||||
run: make -f Makefile.Linux MAILPROXY=true FTP=true
|
||||
- name: regression tests
|
||||
run: python3 tests/run.py
|
||||
- name: regression tests, a thread for each client
|
||||
run: python3 tests/run.py --loopmode off
|
||||
- name: mkdir
|
||||
run: mkdir ~/3proxy
|
||||
- name: make install
|
||||
|
||||
@ -254,9 +254,10 @@ authorization and to drop the per-destination log records only.
|
||||
(for udppm) singlepacket, expect only one packet from both client and server
|
||||
.br
|
||||
.B -L
|
||||
(for TCP services) serve the clients on event loops (see \fBloopmode\fR): a
|
||||
few threads each serve many clients, instead of a thread for each.
|
||||
\fB-L0\fR gives each client a thread of its own whatever \fBloopmode\fR says.
|
||||
(for TCP services) how the clients are served, whatever \fBloopmode\fR says
|
||||
(see there): \fB-L2\fR on event loops, which also relay their data (the
|
||||
default), \fB-L\fR on event loops relaying the data as a thread would,
|
||||
\fB-L0\fR a thread for each client.
|
||||
.br
|
||||
.B -u
|
||||
Never ask for username/password
|
||||
@ -1526,16 +1527,21 @@ many connections were given to a waiting one on its Running Services page.
|
||||
|
||||
.br
|
||||
.BR loopmode
|
||||
\fIon\fR|\fIoff\fR
|
||||
\fIcb\fR|\fIon\fR|\fIoff\fR
|
||||
.br
|
||||
Whether the clients of the TCP services which follow (until the next
|
||||
\fBloopmode\fR) are served on event loops: a few threads (see \fBloops\fR)
|
||||
each wait for the sockets and timers of many clients and switch between
|
||||
them, each client running on a stack of its own as large as its thread's
|
||||
would be. A client costs a stack and no thread, and waking it costs no
|
||||
switch of threads, so many connections take less memory and CPU. Off by
|
||||
default; the \fB-L\fR option of a service overrides it, \fB-L0\fR for a
|
||||
thread for each client.
|
||||
switch of threads, so many connections take less memory and CPU.
|
||||
\fIcb\fR, the default, also has the loop relay a connection's data itself
|
||||
once the request is handled, where nothing but the sockets is between the
|
||||
sides (no filters, no limits but that of a body's length), without
|
||||
switching to the client's stack for each read. \fIon\fR relays the data
|
||||
on the client's stack, as a thread of its own would, and \fIoff\fR gives
|
||||
each client a thread. The \fB-L\fR option of a service overrides it: \fB-L2\fR,
|
||||
\fB-L\fR, \fB-L0\fR.
|
||||
.br
|
||||
Clients keep a thread each, whatever is asked, where something they use
|
||||
would hold up the others sharing their thread: a service with FilePlugin,
|
||||
|
||||
@ -429,7 +429,7 @@ static int h_loops(int argc, unsigned char **argv){
|
||||
static int h_loopmode(int argc, unsigned char **argv){
|
||||
if(!strcmp((char *)argv[1], "on")) conf->loopmode = 1;
|
||||
else if(!strcmp((char *)argv[1], "off")) conf->loopmode = 0;
|
||||
/* and their data relayed by the loop (a draft) */
|
||||
/* and their data relayed by the loop: the default */
|
||||
else if(!strcmp((char *)argv[1], "cb")) conf->loopmode = 2;
|
||||
else return 1;
|
||||
return 0;
|
||||
|
||||
@ -22,6 +22,8 @@
|
||||
.trafcounter = NULL,
|
||||
.services = NULL,
|
||||
.stacksize = 0,
|
||||
/* clients served on event loops, their data relayed by the loops */
|
||||
.loopmode = 2,
|
||||
.poolmax = DEFAULT_POOLMAX,
|
||||
.pooltimeout = DEFAULT_POOLTIMEOUT,
|
||||
.counterd = -1,
|
||||
|
||||
@ -480,7 +480,7 @@ static int srvprepare(struct srvstart *s, int argc, char **argv){
|
||||
srv->stacksize = atoi(argv[i]+2);
|
||||
break;
|
||||
case 'L':
|
||||
/* -L2: and their data relayed by the loop (a draft) */
|
||||
/* -L2: and their data relayed by the loop (the default) */
|
||||
srv->loopmode = argv[i][2]? atoi(argv[i]+2) : 1;
|
||||
break;
|
||||
case 'a':
|
||||
|
||||
@ -7,9 +7,10 @@
|
||||
*/
|
||||
|
||||
/* Clients served on event loops: a few threads, a CPU each by default
|
||||
(loops), each running a loop, and each client of a service given -L (or
|
||||
loopmode on) served by a fiber of one of them, with the same code as a
|
||||
client with a thread of its own: its waits in sockpoll() wait in the loop.
|
||||
(loops), each running a loop, and each client of a service (unless given
|
||||
-L0 or loopmode off) served by a fiber of one of them, with the same code
|
||||
as a client with a thread of its own: its waits in sockpoll() wait in the
|
||||
loop.
|
||||
A service whose clients cannot share a thread (threadperclient), one
|
||||
listening for connections back (-R), all of its clients waiting for the
|
||||
same socket, which a loop waits for once, or a build or processor without
|
||||
@ -426,13 +427,13 @@ DONE:
|
||||
}
|
||||
|
||||
|
||||
/* ---- sockmap() as callbacks (-L2, a draft) ------------------------------- */
|
||||
/* ---- sockmap() as callbacks (-L2, loopmode cb) --------------------------- */
|
||||
|
||||
/* The data of a connection mapped by a fiber of a loop with neither filters,
|
||||
limits but that of a body's length, nor anything but the socket functions of the system between the
|
||||
sides, is relayed by the loop itself: the sockets call it back, on the
|
||||
loop's own stack, and the fiber, parked meanwhile, is resumed only once
|
||||
the mapping is over. No splice() yet: data is copied. */
|
||||
the mapping is over. */
|
||||
|
||||
/* rounds of a read and a write each way at most in a callback, before what
|
||||
is still ready waits for the next turn of the loop */
|
||||
|
||||
@ -1009,7 +1009,8 @@ struct extparam {
|
||||
int filtermaxsize;
|
||||
int poolmax, pooltimeout; /* threadpool: idle workers kept, -1 automatic */
|
||||
int loops; /* threads serving clients on event loops, 0: a CPU each */
|
||||
int loopmode; /* services from here on serve clients on loops */
|
||||
int loopmode; /* services from here on serve clients on loops: 1, and
|
||||
relay their data there: 2 */
|
||||
int gracetraf, gracenum, gracedelay;
|
||||
int maxseg;
|
||||
unsigned char **archiver;
|
||||
|
||||
@ -58,11 +58,14 @@ def main():
|
||||
help="keep the temporary directory")
|
||||
parser.add_argument("-v", "--verbose", action="store_true",
|
||||
help="print every check, not just the failures")
|
||||
parser.add_argument("--loopmode", action="store_true",
|
||||
help="serve the clients of every service on event loops")
|
||||
parser.add_argument("--loopmode", choices=("cb", "on", "off"),
|
||||
help="serve the clients of every service so (cb, the "
|
||||
"default, and on: on two event loops; off: a thread "
|
||||
"each)")
|
||||
args = parser.parse_args()
|
||||
if args.loopmode:
|
||||
os.environ["THREEPROXY_TESTCONFIG"] = "loops 2\nloopmode on\n"
|
||||
os.environ["THREEPROXY_TESTCONFIG"] = \
|
||||
"loops 2\nloopmode %s\n" % args.loopmode
|
||||
|
||||
binary = args.binary or os.environ.get("BIN") or default_binary()
|
||||
binary = os.path.abspath(binary)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user