X-Git-Url: http://git.indexdata.com/?p=yazpp-moved-to-github.git;a=blobdiff_plain;f=src%2Fyaz-pdu-assoc.cpp;h=8d6f577897060493b5e5deee8735a0c3a488798c;hp=cc4094cc17488886e75410ba67444caa59de7f60;hb=0084c40d8bc6babaeb0b833b12d9cd625c807525;hpb=0cc824e02bc2c69986bec8c9dd9ff53f07a0cd3d diff --git a/src/yaz-pdu-assoc.cpp b/src/yaz-pdu-assoc.cpp index cc4094c..8d6f577 100644 --- a/src/yaz-pdu-assoc.cpp +++ b/src/yaz-pdu-assoc.cpp @@ -1,10 +1,11 @@ -/* - * Copyright (c) 1998-2004, Index Data. +/* This file is part of the yazpp toolkit. + * Copyright (C) 1998-2012 Index Data and Mike Taylor * See the file LICENSE for details. - * - * $Id: yaz-pdu-assoc.cpp,v 1.45 2006-03-29 13:14:17 adam Exp $ */ +#if HAVE_CONFIG_H +#include +#endif #include #include #include @@ -12,6 +13,10 @@ #include +#if HAVE_FCNTL_H +#include +#endif + using namespace yazpp_1; void PDU_Assoc::init(ISocketObservable *socketObservable) @@ -30,6 +35,7 @@ void PDU_Assoc::init(ISocketObservable *socketObservable) m_destroyed = 0; m_idleTime = 0; m_log = YLOG_DEBUG; + m_session_is_dead = false; } PDU_Assoc::PDU_Assoc(ISocketObservable *socketObservable) @@ -79,7 +85,7 @@ void PDU_Assoc::socketNotify(int event) this, m_state, event); if (event & SOCKET_OBSERVE_EXCEPT) { - close(); + shutdown(); m_PDU_Observer->failNotify(); return; } @@ -95,7 +101,7 @@ void PDU_Assoc::socketNotify(int event) { yaz_log (m_log, "PDU_Assoc::cs_accept failed"); m_cs = 0; - close(); + shutdown(); m_PDU_Observer->failNotify(); } else @@ -123,7 +129,7 @@ void PDU_Assoc::socketNotify(int event) event & SOCKET_OBSERVE_WRITE) { // For Unix: if both read and write is set, then connect failed. - close(); + shutdown(); m_PDU_Observer->failNotify(); } else @@ -199,7 +205,7 @@ void PDU_Assoc::socketNotify(int event) else if (res <= 0) { yaz_log (m_log, "PDU_Assoc::Connection closed by peer"); - close(); + shutdown(); if (m_PDU_Observer) m_PDU_Observer->failNotify(); // problem here.. return; @@ -234,21 +240,31 @@ void PDU_Assoc::socketNotify(int event) break; case Closed: yaz_log (m_log, "CLOSING state=%d event was %d", m_state, event); - close(); + shutdown(); m_PDU_Observer->failNotify(); break; default: yaz_log (m_log, "Unknown state=%d event was %d", m_state, event); - close(); + shutdown(); m_PDU_Observer->failNotify(); } } -void PDU_Assoc::close() +void PDU_Assoc::close_session() +{ + m_session_is_dead = true; + if (!m_queue_out) + { + shutdown(); + m_PDU_Observer->failNotify(); + } +} + +void PDU_Assoc::shutdown() { PDU_Assoc *ch; for (ch = m_children; ch; ch = ch->m_next) - ch->close(); + ch->shutdown(); m_socketObservable->deleteObserver(this); m_state = Closed; @@ -271,7 +287,7 @@ void PDU_Assoc::close() void PDU_Assoc::destroy() { - close(); + shutdown(); if (m_destroyed) *m_destroyed = 1; @@ -331,13 +347,18 @@ int PDU_Assoc::flush_PDU() m_socketObservable->maskObserver(this, SOCKET_OBSERVE_READ| SOCKET_OBSERVE_WRITE| SOCKET_OBSERVE_EXCEPT); + if (m_session_is_dead) + { + shutdown(); + m_PDU_Observer->failNotify(); + } return 0; } r = cs_put (m_cs, q->m_buf, q->m_len); if (r < 0) { yaz_log (m_log, "PDU_Assoc::flush_PDU cs_put failed"); - close(); + shutdown(); m_PDU_Observer->failNotify(); return r; } @@ -401,7 +422,7 @@ COMSTACK PDU_Assoc::comstack(const char *type_and_host, void **vp) int PDU_Assoc::listen(IPDU_Observer *observer, const char *addr) { - close(); + shutdown(); m_PDU_Observer = observer; void *ap; @@ -411,11 +432,21 @@ int PDU_Assoc::listen(IPDU_Observer *observer, const char *addr) return -1; if (cs_bind(m_cs, ap, CS_SERVER) < 0) return -2; - m_socketObservable->addObserver(cs_fileno(m_cs), this); + + int fd = cs_fileno(m_cs); +#if HAVE_FCNTL_H + int oldflags = fcntl(fd, F_GETFD, 0); + if (oldflags >= 0) + { + oldflags |= FD_CLOEXEC; + fcntl(fd, F_SETFD, oldflags); + } +#endif + m_socketObservable->addObserver(fd, this); yaz_log(m_log, "maskObserver 9"); m_socketObservable->maskObserver(this, SOCKET_OBSERVE_READ| SOCKET_OBSERVE_EXCEPT); - yaz_log (m_log, "PDU_Assoc::listen ok fd=%d", cs_fileno(m_cs)); + yaz_log (m_log, "PDU_Assoc::listen ok fd=%d", fd); m_state = Listen; return 0; } @@ -430,7 +461,7 @@ void PDU_Assoc::idleTime(int idleTime) int PDU_Assoc::connect(IPDU_Observer *observer, const char *addr) { yaz_log (m_log, "PDU_Assoc::connect %s", addr); - close(); + shutdown(); m_PDU_Observer = observer; void *ap; m_cs = comstack(addr, &ap); @@ -478,13 +509,19 @@ void PDU_Assoc::childNotify(COMSTACK cs) PDU_Assoc *new_observable = new PDU_Assoc (m_socketObservable, cs); - new_observable->m_next = m_children; - m_children = new_observable; - new_observable->m_parent = this; - // Clone PDU Observer new_observable->m_PDU_Observer = m_PDU_Observer->sessionNotify (new_observable, cs_fileno(cs)); + + if (!new_observable->m_PDU_Observer) + { + new_observable->shutdown(); + delete new_observable; + return; + } + new_observable->m_next = m_children; + m_children = new_observable; + new_observable->m_parent = this; } const char*PDU_Assoc::getpeername() @@ -496,6 +533,7 @@ const char*PDU_Assoc::getpeername() /* * Local variables: * c-basic-offset: 4 + * c-file-style: "Stroustrup" * indent-tabs-mode: nil * End: * vim: shiftwidth=4 tabstop=8 expandtab