Commit e0d2f990 authored by jan.koester's avatar jan.koester
Browse files

test

parent 1ffe77a2
Loading
Loading
Loading
Loading
+36 −26
Original line number Diff line number Diff line
@@ -342,43 +342,53 @@ namespace netplus {
        }

        void CloseEventHandler(int pos, const int tid, ULONG_PTR args) {
            std::lock_guard<std::mutex> global_lock(POLL_HANDLER_MUTEX);

            if (!_Events[pos].data.ptr) {
                return;
            }

            con* ccon = reinterpret_cast<con*>(_Events[pos].data.ptr);
            if (!ccon) return;

            if (!ccon) {
                return;
            }
            // Lock connection first (prevents concurrent Read/Write handlers on same con)
            std::unique_lock<std::mutex> conn_lock(ccon->event_mutex);

            if (ccon->csock) {
                try {
                    if (epoll_ctl(_pollFD, EPOLL_CTL_DEL, ccon->csock->fd(), nullptr) < 0) {
            // Cache fd early; after close it may be invalid / reused
            int fd = -1;
            if (ccon->csock) fd = ccon->csock->fd();

            // 1) Remove from epoll (ignore ENOENT / EBADF)
            if (fd >= 0) {
                if (epoll_ctl(_pollFD, EPOLL_CTL_DEL, fd, nullptr) < 0) {
                    if (errno != ENOENT && errno != EBADF) {
                        // Log, but continue cleanup anyway
                        NetException except;
                        char errstr[255];
                        strerror_r_netplus(errno, errstr, 255);
                        except[NetException::Error] << "CloseEventHandler: can't close socket to epoll: " << errstr;
                        throw except;
                        except[NetException::Error]
                            << "CloseEventHandler: failed to remove fd from epoll: " << errstr;
                        // don't throw here; still must cleanup safely
                    }
                }
            }

            // 2) Inform application layer (do NOT hold global map lock here)
            try {
                evconnection->DisconnectEvent(*ccon, tid, args);
            } catch (...) {
                // don't let DisconnectEvent prevent cleanup
            }

                    ccon->csock->close();

                    CONNECTIONS.erase(ccon->csock->fd());

                } catch (NetException &e) {
                    CONNECTIONS.erase(ccon->csock->fd());
                    conn_lock.unlock();
                    throw e;
            // 3) Close socket
            if (ccon->csock) {
                try { ccon->csock->close(); } catch (...) {}
            }

            // 4) Remove from global map (use cached fd)
            {
                std::lock_guard<std::mutex> global_lock(POLL_HANDLER_MUTEX);
                if (fd >= 0) CONNECTIONS.erase(fd);
            }

            // 5) Clear epoll event slot pointer
            _Events[pos].data.ptr = nullptr;

            // 6) Destroy connection object
            conn_lock.unlock();
            delete ccon;
        }