Loading src/event/kqueue.cpp +21 −34 Original line number Diff line number Diff line Loading @@ -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)); Loading Loading
src/event/kqueue.cpp +21 −34 Original line number Diff line number Diff line Loading @@ -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)); Loading