Commit 4b480dd9 authored by jan.koester's avatar jan.koester
Browse files

test

parent 7b95adce
Loading
Loading
Loading
Loading
+21 −34
Original line number Diff line number Diff line
@@ -172,73 +172,60 @@ namespace netplus {
        void ConnectEventHandler(int pos, const int tid, ULONG_PTR args) {
            NetException exception;

            // 1) Create connection object using shared_ptr for reference counting
            // Note: Ensure your eventapi::CreateConnection supports std::shared_ptr<con>&
            std::shared_ptr<con> ccon = std::make_shared<con>();
            evconnection->CreateConnection(ccon);
            // 1) Create as unique_ptr to satisfy the API requirement
            std::unique_ptr<con> ucon;
            evconnection->CreateConnection(ucon);

            if (!ccon) {
            if (!ucon) {
                std::cerr << "ConnectEventHandler: CreateConnection returned null\n";
                return;
            }

            // 2) Create the right socket
            // 2) Initialize socket (TCP, UDP, or SSL)
            if (_ServerSocket->_Type == sockettype::TCP) {
                ccon->csock = std::make_unique<tcp>(-1);
                ucon->csock = std::make_unique<tcp>(-1);
            } else if (_ServerSocket->_Type == sockettype::UDP) {
                ccon->csock = std::make_unique<udp>(-1);
                ucon->csock = std::make_unique<udp>(-1);
            } else if (_ServerSocket->_Type == sockettype::SSL) {
                netplus::ssl* srv = static_cast<netplus::ssl*>(_ServerSocket);
                ccon->csock = std::make_unique<ssl>(srv->_cert, -1);
                ucon->csock = std::make_unique<ssl>(srv->_cert, -1);
            } else {
                exception[NetException::Error] << "ConnectEventHandler: unsupported socket type";
                throw exception;
            }

            if (!ccon->csock) {
                exception[NetException::Error] << "ConnectEventHandler: failed to create client socket";
                throw exception;
            }

            // 3) Accept and 4) Set Nonblocking
            _ServerSocket->accept(ccon->csock);

            // 3) Accept and Set Nonblocking
            _ServerSocket->accept(ucon->csock);
            try {
                ccon->csock->setFlag(O_NONBLOCK, 1);
                ucon->csock->setFlag(O_NONBLOCK, 1);
            } catch (NetException& e) {
                try { ccon->csock->close(); } catch (...) {}
                try { ucon->csock->close(); } catch (...) {}
                throw;
            }

            ccon->lasteventime = time(nullptr);
            ucon->lasteventime = time(nullptr);

            // 4) Transfer ownership to shared_ptr for global management
            // This allows the map to hold the object even if ucon goes out of scope.
            std::shared_ptr<con> ccon(ucon.release());

            // IMPORTANT: In kqueue, udata stores a raw pointer.
            // The shared_ptr in the CONNECTIONS map keeps this memory alive.
            con* raw = ccon.get();
            int fd = ccon->csock->fd();

            // 6) Register initial READ (oneshot)
            // 5) Register with kqueue
            struct kevent kev;
            EV_SET(&kev,
                fd,
                EVFILT_READ,
                EV_ADD | EV_ENABLE | EV_ONESHOT,
                0,
                0,
                raw);
            EV_SET(&kev, fd, EVFILT_READ, EV_ADD | EV_ENABLE | EV_ONESHOT, 0, 0, raw);

            if (kevent(_pollFD, &kev, 1, nullptr, 0, nullptr) < 0) {
                char errstr[255];
                strerror_r_netplus(errno, errstr, 255);
                exception[NetException::Error] << "ConnectEventHandler: can't add socket to kqueue: " << errstr;
                exception[NetException::Error] << "ConnectEventHandler: kqueue add failed: " << errstr;
                throw exception;
            }

            // 7) Inform protocol layer
            // 6) Inform protocol layer and publish to global map
            evconnection->ConnectEvent(*raw, tid, args);

            // 8) Publish to global map
            // This increments the reference count. The object is now managed by the map.
            {
                std::lock_guard<std::mutex> glk(POLL_HANDLER_MUTEX);
                CONNECTIONS.emplace(fd, std::move(ccon));