Commit 27aa5774 authored by jan.koester's avatar jan.koester
Browse files

test

parent 398fdf51
Loading
Loading
Loading
Loading
+15 −2
Original line number Diff line number Diff line
@@ -3480,8 +3480,21 @@ namespace netplus {
                sent = _socket->sendRaw(raw_buf, 0);
            } catch (NetException& e) {
                if (e.getErrorType() == NetException::Note) {
                    // IOCP write already pending — stop flushing;
                    // records remain queued for the next write completion.
                    if (_socket->isBlocking()) {
                        // A blocking socket can only report EAGAIN/EWOULDBLOCK here if a
                        // SO_SNDTIMEO deadline was configured and just expired -- there is no
                        // event loop that will ever come back and retry this write for us
                        // (unlike the non-blocking case below), so silently returning here
                        // would leave send_record/send_queue's bytes stuck forever while every
                        // caller up the stack (tls::sendData()'s own Note-swallowing catch,
                        // ultimately the application) believes the write already succeeded.
                        // Surface it as a real failure instead.
                        NetException timeout;
                        timeout[NetException::Error] << "tls::flush_out: send timed out";
                        throw timeout;
                    }
                    // Non-blocking socket not yet writable (or an IOCP write already pending) --
                    // stop flushing; records remain queued for the next write completion.
                    return;
                }
                throw;
+12 −0
Original line number Diff line number Diff line
@@ -188,10 +188,12 @@ void tcp::listen() {

void tcp::setNonBlock() {
    setFlag(O_NONBLOCK, 1);
    _blocking = false;
}

void tcp::setBlock() {
    setFlag(O_NONBLOCK, 0);
    _blocking = true;
}

int tcp::getMaxconnections() {
@@ -239,6 +241,16 @@ void tcp::accept(std::unique_ptr<socket>& csock, bool nonblock) {
    csock->_Addr = peer;
    csock->_AddrLen = peerLen;

    // Both branches above set the OS-level flag directly on the raw fd (accept4's flag, or a
    // manual fcntl on `cfd` before csock even owns it) rather than through csock's own
    // setNonBlock() -- keep its tracked isBlocking() state consistent with what the fd actually
    // is, now that csock does own it. Matters beyond bookkeeping: tls::flush_out() relies on
    // isBlocking() to tell a genuine send timeout (blocking) apart from "not writable yet, event
    // loop will retry" (non-blocking) -- every accepted connection is non-blocking by
    // construction (this is the event loop's own accept path), so getting this wrong here would
    // make flush_out() treat completely normal EAGAINs as hard failures.
    if (nonblock) csock->setNonBlock();

    // Disable Nagle's algorithm — reduces latency for small HTTP frames
    int one = 1;
    ::setsockopt(cfd, IPPROTO_TCP, TCP_NODELAY, &one, sizeof(one));
+2 −0
Original line number Diff line number Diff line
@@ -192,10 +192,12 @@ void udp::listen() {

void udp::setNonBlock() {
    setFlag(O_NONBLOCK, 1);
    _blocking = false;
}

void udp::setBlock() {
    setFlag(O_NONBLOCK, 0);
    _blocking = true;
}

int udp::getMaxconnections() {
+10 −0
Original line number Diff line number Diff line
@@ -258,6 +258,15 @@ namespace netplus {
		bool _Bound    = false;
		bool _Listening = false;

		// Tracked by every setBlock()/setNonBlock() override so callers -- notably
		// tls::flush_out() -- can tell whether an EAGAIN/EWOULDBLOCK just observed on this fd
		// means "try again once the event loop says writable" (non-blocking: expected, normal)
		// or "the SO_SNDTIMEO/SO_RCVTIMEO deadline just expired" (blocking: a genuinely blocking
		// socket without a timeout configured cannot return EAGAIN at all, so for a blocking
		// socket this is unambiguously a timeout, not a retry hint). Defaults to true since a
		// freshly created fd is blocking until something calls setNonBlock().
		bool isBlocking() const { return _blocking; }

		// Mark this socket as associated with an IOCP handle.
		// Only IOCP-bound sockets should use overlapped WSASend/WSARecv.
		void setIocpAssociated(bool v) { _iocpAssociated = v; }
@@ -266,6 +275,7 @@ namespace netplus {
	protected:
		std::atomic<bool> _pendingIocpWrite{false};
		bool _iocpAssociated = false;
		bool _blocking = true; // see isBlocking() above; kept up to date by setBlock()/setNonBlock()
		// ✅ legacy helper still available -- copies from an addrinfo owned by
		// the caller (e.g. still-linked into getaddrinfo()'s result list), no
		// allocation/ownership of its own. See setAddrFromAI() below, which
+2 −0
Original line number Diff line number Diff line
@@ -116,6 +116,7 @@ void tcp::listen() {
void tcp::setNonBlock() {
    u_long mode = 1;
    ::ioctlsocket(_Socket, FIONBIO, &mode);
    _blocking = false;
}

int tcp::getMaxconnections() {
@@ -435,6 +436,7 @@ void tcp::setBlock() {
        e[NetException::Error] << "tcp::setBlock failed";
        throw e;
    }
    _blocking = true;
}

void tcp::accept(LPFN_ACCEPTEX lpfnAcceptEx, std::unique_ptr<socket>& csock) {
Loading