Loading src/event/kqueue.cpp +11 −24 Original line number Diff line number Diff line Loading @@ -172,8 +172,9 @@ namespace netplus { void ConnectEventHandler(int pos, const int tid, ULONG_PTR args) { NetException exception; // 1) Create connection object (HttpRequest etc.) std::unique_ptr<con> ccon; // 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); if (!ccon) { Loading @@ -199,42 +200,29 @@ namespace netplus { throw exception; } // 3) Accept // 3) Accept and 4) Set Nonblocking _ServerSocket->accept(ccon->csock); // 4) Nonblocking try { ccon->csock->setFlag(O_NONBLOCK, 1); } catch (NetException& e) { // Accept succeeded but nonblock failed -> close immediately try { ccon->csock->close(); } catch (...) {} throw; } // 5) Optional log try { std::string ip; ccon->csock->getAddress(ip); std::cout << "Connected: " << ip << std::endl; } catch (...) { // ignore logging failures } ccon->lasteventime = time(nullptr); // IMPORTANT: kqueue stores the udata pointer; it must remain valid. // We'll only release ownership once the socket is registered successfully. // 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) // Use EV_CLEAR if you want edge-trigger-ish behavior. // If you prefer level-trigger: omit EV_CLEAR. struct kevent kev; EV_SET(&kev, fd, EVFILT_READ, EV_ADD | EV_ENABLE | EV_ONESHOT /* | EV_CLEAR */, EV_ADD | EV_ENABLE | EV_ONESHOT, 0, 0, raw); Loading @@ -246,16 +234,15 @@ namespace netplus { throw exception; } // 7) Inform protocol layer once (do NOT call repeatedly in write handler) // 7) Inform protocol layer evconnection->ConnectEvent(*raw, tid, args); // 8) Publish to global map and release ownership // 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, raw); CONNECTIONS.emplace(fd, std::move(ccon)); } ccon.release(); // ownership transferred to event loop lifetime management } void ReadEventHandler(int pos, const int tid, ULONG_PTR args) { Loading Loading
src/event/kqueue.cpp +11 −24 Original line number Diff line number Diff line Loading @@ -172,8 +172,9 @@ namespace netplus { void ConnectEventHandler(int pos, const int tid, ULONG_PTR args) { NetException exception; // 1) Create connection object (HttpRequest etc.) std::unique_ptr<con> ccon; // 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); if (!ccon) { Loading @@ -199,42 +200,29 @@ namespace netplus { throw exception; } // 3) Accept // 3) Accept and 4) Set Nonblocking _ServerSocket->accept(ccon->csock); // 4) Nonblocking try { ccon->csock->setFlag(O_NONBLOCK, 1); } catch (NetException& e) { // Accept succeeded but nonblock failed -> close immediately try { ccon->csock->close(); } catch (...) {} throw; } // 5) Optional log try { std::string ip; ccon->csock->getAddress(ip); std::cout << "Connected: " << ip << std::endl; } catch (...) { // ignore logging failures } ccon->lasteventime = time(nullptr); // IMPORTANT: kqueue stores the udata pointer; it must remain valid. // We'll only release ownership once the socket is registered successfully. // 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) // Use EV_CLEAR if you want edge-trigger-ish behavior. // If you prefer level-trigger: omit EV_CLEAR. struct kevent kev; EV_SET(&kev, fd, EVFILT_READ, EV_ADD | EV_ENABLE | EV_ONESHOT /* | EV_CLEAR */, EV_ADD | EV_ENABLE | EV_ONESHOT, 0, 0, raw); Loading @@ -246,16 +234,15 @@ namespace netplus { throw exception; } // 7) Inform protocol layer once (do NOT call repeatedly in write handler) // 7) Inform protocol layer evconnection->ConnectEvent(*raw, tid, args); // 8) Publish to global map and release ownership // 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, raw); CONNECTIONS.emplace(fd, std::move(ccon)); } ccon.release(); // ownership transferred to event loop lifetime management } void ReadEventHandler(int pos, const int tid, ULONG_PTR args) { Loading