MCPcopy Create free account
hub / github.com/Selectively11/CloudRedirect / AcceptLoop

Function AcceptLoop

src/platform/win/http_server.cpp:480–545  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

478}
479
480static void AcceptLoop() {
481 LOG("[HTTP] Accept loop started on port %u", g_port.load());
482 while (g_running.load()) {
483 // use select with a timeout so we can check g_running periodically
484 fd_set readfds;
485 FD_ZERO(&readfds);
486 FD_SET(g_listenSock, &readfds);
487
488 timeval tv;
489 tv.tv_sec = 1;
490 tv.tv_usec = 0;
491
492 int sel = select(0, &readfds, nullptr, nullptr, &tv);
493 if (sel <= 0) continue;
494
495 SOCKET client = accept(g_listenSock, nullptr, nullptr);
496 if (client == INVALID_SOCKET) continue;
497
498 // Reject connections from other processes
499 if (!IsConnectionFromSteam(client)) {
500 closesocket(client);
501 continue;
502 }
503
504 // SO_SNDTIMEO matters too: a stalled final send() can wedge a slot and saturate the thread cap.
505 DWORD rcvTimeout = 30000; // 30s
506 DWORD sndTimeout = 30000; // 30s
507 setsockopt(client, SOL_SOCKET, SO_RCVTIMEO, (const char*)&rcvTimeout, sizeof(rcvTimeout));
508 setsockopt(client, SOL_SOCKET, SO_SNDTIMEO, (const char*)&sndTimeout, sizeof(sndTimeout));
509
510 // handle each connection on its own thread so parallel uploads don't queue up
511 {
512 std::lock_guard<std::mutex> lk(g_clientMtx);
513 PruneClientThreads();
514
515 // At the cap: backpressure instead of rejecting. A closed socket surfaces
516 // as a Steam cloud error; waiting for a slot lets large bursts drain.
517 int waitMs = 0;
518 while (g_clientSlots.size() >= kMaxClientThreads && g_running.load() &&
519 waitMs < kAcceptBackpressureMaxMs) {
520 std::this_thread::sleep_for(std::chrono::milliseconds(20));
521 waitMs += 20;
522 PruneClientThreads();
523 }
524 if (g_clientSlots.size() >= kMaxClientThreads) {
525 LOG("[HTTP] Thread cap (%zu) still full after %dms, rejecting connection",
526 kMaxClientThreads, waitMs);
527 closesocket(client);
528 continue;
529 }
530
531 auto doneFlag = std::make_shared<std::atomic<bool>>(false);
532 auto wrapper = [doneFlag](SOCKET s) {
533 HandleClient(s);
534 doneFlag->store(true);
535 };
536 try {
537 g_clientSlots.push_back({std::thread(wrapper, client), doneFlag});

Callers

nothing calls this directly

Calls 4

PruneClientThreadsFunction · 0.85
HandleClientFunction · 0.85
sizeMethod · 0.80
IsConnectionFromSteamFunction · 0.70

Tested by

no test coverage detected