From 97118338f9ac93e767e5589d449d3f9abacb3190 Mon Sep 17 00:00:00 2001 From: Adam Dickmeiss Date: Thu, 28 Jan 1999 13:08:39 +0000 Subject: [PATCH] Yaz_PDU_Assoc better encapsulated. Memory leak fix in yaz-socket-manager.cc. --- include/yaz-ir-assoc.h | 12 ++++-- include/yaz-pdu-assoc.h | 11 ++++- include/yaz-pdu-observer.h | 10 ++++- src/yaz-client.cpp | 11 +++-- src/yaz-ir-assoc.cpp | 12 ++++-- src/yaz-pdu-assoc.cpp | 99 +++++++++++++++++++++++++------------------- src/yaz-proxy-main.cpp | 11 +++-- src/yaz-proxy.cpp | 10 ++++- src/yaz-server.cpp | 32 ++++++++++---- src/yaz-socket-manager.cpp | 13 ++++-- 10 files changed, 145 insertions(+), 76 deletions(-) diff --git a/include/yaz-ir-assoc.h b/include/yaz-ir-assoc.h index e615c0a..bc36343 100644 --- a/include/yaz-ir-assoc.h +++ b/include/yaz-ir-assoc.h @@ -4,8 +4,12 @@ * Sebastian Hammer, Adam Dickmeiss * * $Log: yaz-ir-assoc.h,v $ - * Revision 1.1 1999-01-28 09:41:07 adam - * Initial revision + * Revision 1.2 1999-01-28 13:08:39 adam + * Yaz_PDU_Assoc better encapsulated. Memory leak fix in + * yaz-socket-manager.cc. + * + * Revision 1.1.1.1 1999/01/28 09:41:07 adam + * First implementation of YAZ++. * */ @@ -17,7 +21,7 @@ /** Information Retrieval Assocation. This object implements the client - and server role of a generic Z39.50 Association. - */ +*/ class Yaz_IR_Assoc : public IYaz_PDU_Observer { public: /// Create object using the PDU Observer specified @@ -43,7 +47,7 @@ class Yaz_IR_Assoc : public IYaz_PDU_Observer { /// Receive Z39.50 PDU virtual void recv_Z_PDU (Z_APDU *apdu) = 0; /// Create Z39.50 with reasonable defaults - Z_APDU *create_Z_PDU(int type); + Z_APDU *create_Z_PDU(int type); private: IYaz_PDU_Observable *m_PDU_Observable; ODR m_odr_in; diff --git a/include/yaz-pdu-assoc.h b/include/yaz-pdu-assoc.h index 079a55f..425a230 100644 --- a/include/yaz-pdu-assoc.h +++ b/include/yaz-pdu-assoc.h @@ -4,8 +4,12 @@ * Sebastian Hammer, Adam Dickmeiss * * $Log: yaz-pdu-assoc.h,v $ - * Revision 1.1 1999-01-28 09:41:07 adam - * Initial revision + * Revision 1.2 1999-01-28 13:08:40 adam + * Yaz_PDU_Assoc better encapsulated. Memory leak fix in + * yaz-socket-manager.cc. + * + * Revision 1.1.1.1 1999/01/28 09:41:07 adam + * First implementation of YAZ++. * */ @@ -41,6 +45,7 @@ class Yaz_PDU_Assoc : public IYaz_PDU_Observable, IYazSocketObserver { int m_input_len; PDU_Queue *m_queue_out; int Yaz_PDU_Assoc::flush_PDU(); + int *m_destroyed; public: /// Create object using specified socketObservable Yaz_PDU_Assoc(IYazSocketObservable *socketObservable, COMSTACK cs); @@ -58,4 +63,6 @@ class Yaz_PDU_Assoc : public IYaz_PDU_Observable, IYazSocketObserver { void socketNotify(int event); /// Close socket void close(); + /// Close and destroy + void destroy(); }; diff --git a/include/yaz-pdu-observer.h b/include/yaz-pdu-observer.h index eef08b4..e2f5961 100644 --- a/include/yaz-pdu-observer.h +++ b/include/yaz-pdu-observer.h @@ -4,8 +4,12 @@ * Sebastian Hammer, Adam Dickmeiss * * $Log: yaz-pdu-observer.h,v $ - * Revision 1.1 1999-01-28 09:41:07 adam - * Initial revision + * Revision 1.2 1999-01-28 13:08:41 adam + * Yaz_PDU_Assoc better encapsulated. Memory leak fix in + * yaz-socket-manager.cc. + * + * Revision 1.1.1.1 1999/01/28 09:41:07 adam + * First implementation of YAZ++. * */ @@ -32,6 +36,8 @@ class IYaz_PDU_Observable { virtual void close() = 0; /// Make clone of this object using this interface virtual IYaz_PDU_Observable *clone() = 0; + /// Destroy completely + virtual void destroy() = 0; }; /** Protocol Data Unit Observer. diff --git a/src/yaz-client.cpp b/src/yaz-client.cpp index 20c3ced..c5166e9 100644 --- a/src/yaz-client.cpp +++ b/src/yaz-client.cpp @@ -4,8 +4,12 @@ * Sebastian Hammer, Adam Dickmeiss * * $Log: yaz-client.cpp,v $ - * Revision 1.1 1999-01-28 09:41:07 adam - * Initial revision + * Revision 1.2 1999-01-28 13:08:42 adam + * Yaz_PDU_Assoc better encapsulated. Memory leak fix in + * yaz-socket-manager.cc. + * + * Revision 1.1.1.1 1999/01/28 09:41:07 adam + * First implementation of YAZ++. * */ @@ -72,8 +76,7 @@ int main(int argc, char **argv) { Yaz_SocketManager mySocketManager; - Yaz_PDU_Assoc my_PDU_Assoc(&mySocketManager, 0); - MyClient z(&my_PDU_Assoc); + MyClient z(new Yaz_PDU_Assoc(&mySocketManager, 0)); z.client("localhost:9999"); z.sendInit(); diff --git a/src/yaz-ir-assoc.cpp b/src/yaz-ir-assoc.cpp index ccaa002..d277643 100644 --- a/src/yaz-ir-assoc.cpp +++ b/src/yaz-ir-assoc.cpp @@ -4,8 +4,12 @@ * Sebastian Hammer, Adam Dickmeiss * * $Log: yaz-ir-assoc.cpp,v $ - * Revision 1.1 1999-01-28 09:41:07 adam - * Initial revision + * Revision 1.2 1999-01-28 13:08:43 adam + * Yaz_PDU_Assoc better encapsulated. Memory leak fix in + * yaz-socket-manager.cc. + * + * Revision 1.1.1.1 1999/01/28 09:41:07 adam + * First implementation of YAZ++. * */ @@ -22,8 +26,8 @@ Yaz_IR_Assoc::Yaz_IR_Assoc(IYaz_PDU_Observable *the_PDU_Observable) Yaz_IR_Assoc::~Yaz_IR_Assoc() { - if (m_PDU_Observable) - m_PDU_Observable->close(); + m_PDU_Observable->destroy(); + delete m_PDU_Observable; odr_destroy (m_odr_print); odr_destroy (m_odr_out); odr_destroy (m_odr_in); diff --git a/src/yaz-pdu-assoc.cpp b/src/yaz-pdu-assoc.cpp index 6056b2d..5350092 100644 --- a/src/yaz-pdu-assoc.cpp +++ b/src/yaz-pdu-assoc.cpp @@ -4,8 +4,12 @@ * Sebastian Hammer, Adam Dickmeiss * * $Log: yaz-pdu-assoc.cpp,v $ - * Revision 1.1 1999-01-28 09:41:07 adam - * Initial revision + * Revision 1.2 1999-01-28 13:08:44 adam + * Yaz_PDU_Assoc better encapsulated. Memory leak fix in + * yaz-socket-manager.cc. + * + * Revision 1.1.1.1 1999/01/28 09:41:07 adam + * First implementation of YAZ++. * */ @@ -29,6 +33,7 @@ Yaz_PDU_Assoc::Yaz_PDU_Assoc(IYazSocketObservable *socketObservable, m_children = 0; m_parent = 0; m_next = 0; + m_destroyed = 0; } IYaz_PDU_Observable *Yaz_PDU_Assoc::clone() @@ -39,31 +44,7 @@ IYaz_PDU_Observable *Yaz_PDU_Assoc::clone() Yaz_PDU_Assoc::~Yaz_PDU_Assoc() { - Yaz_PDU_Assoc **c; - close(); - - logf (LOG_LOG, "m_children=%p m_parent=%p", m_children, - m_parent); - // delete from parent's child list (if any) - if (m_parent) - { - c = &m_parent->m_children; - while (*c != this) - { - assert (*c); - c = &(*c)->m_next; - } - *c = (*c)->m_next; - } - // delete all children ... - c = &m_children; - while (*c) - { - Yaz_PDU_Assoc *here = *c; - *c = (*c)->m_next; - here->m_parent = 0; - delete here; - } + destroy(); } void Yaz_PDU_Assoc::socketNotify(int event) @@ -95,7 +76,6 @@ void Yaz_PDU_Assoc::socketNotify(int event) } else if (m_state == Listen) { - logf (LOG_LOG, "handler_listen %d", event); if (event & YAZ_SOCKET_OBSERVE_READ) { int res; @@ -129,12 +109,10 @@ void Yaz_PDU_Assoc::socketNotify(int event) { if (event & YAZ_SOCKET_OBSERVE_WRITE) { - logf (LOG_LOG, "socketNotify write"); flush_PDU(); } if (event & YAZ_SOCKET_OBSERVE_READ) { - logf (LOG_LOG, "socketNotify read"); do { int res = cs_get (m_cs, &m_input_buf, &m_input_len); @@ -142,13 +120,19 @@ void Yaz_PDU_Assoc::socketNotify(int event) return; else if (res <= 0) { - logf (LOG_LOG, "Connection closed by server"); + logf (LOG_LOG, "Connection closed by client"); close(); m_PDU_Observer->failNotify(); return; } + // lock it, so we know if recv_PDU deletes it. + int destroyed = 0; + m_destroyed = &destroyed; + m_PDU_Observer->recv_PDU(m_input_buf, res); - } while (cs_more (m_cs)); + if (destroyed) // it really was destroyed, return now. + return; + } while (m_cs && cs_more (m_cs)); } } } @@ -175,6 +159,35 @@ void Yaz_PDU_Assoc::close() m_input_len = 0; } +void Yaz_PDU_Assoc::destroy() +{ + close(); + if (m_destroyed) + *m_destroyed = 1; + Yaz_PDU_Assoc **c; + + // delete from parent's child list (if any) + if (m_parent) + { + c = &m_parent->m_children; + while (*c != this) + { + assert (*c); + c = &(*c)->m_next; + } + *c = (*c)->m_next; + } + // delete all children ... + c = &m_children; + while (*c) + { + Yaz_PDU_Assoc *here = *c; + *c = (*c)->m_next; + here->m_parent = 0; + delete here; + } +} + Yaz_PDU_Assoc::PDU_Queue::PDU_Queue(const char *buf, int len) { m_buf = (char *) malloc (len); @@ -192,7 +205,6 @@ int Yaz_PDU_Assoc::flush_PDU() { int r; - logf (LOG_LOG, "flush_PDU fd=%d", cs_fileno(m_cs)); if (m_state != Ready) return 1; PDU_Queue *q = m_queue_out; @@ -234,8 +246,6 @@ int Yaz_PDU_Assoc::send_PDU(const char *buf, int len) PDU_Queue **pq = &m_queue_out; int is_idle = (*pq ? 0 : 1); - logf (LOG_LOG, "send_PDU, m_queue_out=%p fd=%d", m_queue_out, - cs_fileno(m_cs)); if (!m_cs) { logf (LOG_LOG, "send_PDU failed, m_cs == 0"); @@ -302,14 +312,17 @@ void Yaz_PDU_Assoc::connect(IYaz_PDU_Observer *observer, { logf (LOG_DEBUG, "Yaz_PDU_Assoc::connect failed"); close (); - return; } - m_socketObservable->addObserver(cs_fileno(cs), this); - m_socketObservable->maskObserver(this, YAZ_SOCKET_OBSERVE_READ| - YAZ_SOCKET_OBSERVE_EXCEPT| - YAZ_SOCKET_OBSERVE_WRITE); - if (res == 1) - m_state = Connecting; else - m_state = Connected; + { + logf (LOG_LOG, "Yaz_PDU_Assoc::connect fd=%d", cs_fileno(cs)); + m_socketObservable->addObserver(cs_fileno(cs), this); + m_socketObservable->maskObserver(this, YAZ_SOCKET_OBSERVE_READ| + YAZ_SOCKET_OBSERVE_EXCEPT| + YAZ_SOCKET_OBSERVE_WRITE); + if (res == 1) + m_state = Connecting; + else + m_state = Connected; + } } diff --git a/src/yaz-proxy-main.cpp b/src/yaz-proxy-main.cpp index 20592b4..891763b 100644 --- a/src/yaz-proxy-main.cpp +++ b/src/yaz-proxy-main.cpp @@ -4,8 +4,12 @@ * Sebastian Hammer, Adam Dickmeiss * * $Log: yaz-proxy-main.cpp,v $ - * Revision 1.1 1999-01-28 09:41:07 adam - * Initial revision + * Revision 1.2 1999-01-28 13:08:45 adam + * Yaz_PDU_Assoc better encapsulated. Memory leak fix in + * yaz-socket-manager.cc. + * + * Revision 1.1.1.1 1999/01/28 09:41:07 adam + * First implementation of YAZ++. * */ @@ -16,8 +20,7 @@ int main(int argc, char **argv) { Yaz_SocketManager mySocketManager; - Yaz_PDU_Assoc *my_PDU_Assoc = new Yaz_PDU_Assoc(&mySocketManager, 0); - Yaz_Proxy proxy(my_PDU_Assoc); + Yaz_Proxy proxy(new Yaz_PDU_Assoc(&mySocketManager, 0)); proxy.server("@:9999"); while (mySocketManager.processEvent() > 0) diff --git a/src/yaz-proxy.cpp b/src/yaz-proxy.cpp index 83bf5db..a37500a 100644 --- a/src/yaz-proxy.cpp +++ b/src/yaz-proxy.cpp @@ -4,8 +4,12 @@ * Sebastian Hammer, Adam Dickmeiss * * $Log: yaz-proxy.cpp,v $ - * Revision 1.1 1999-01-28 09:41:07 adam - * Initial revision + * Revision 1.2 1999-01-28 13:08:46 adam + * Yaz_PDU_Assoc better encapsulated. Memory leak fix in + * yaz-socket-manager.cc. + * + * Revision 1.1.1.1 1999/01/28 09:41:07 adam + * First implementation of YAZ++. * */ @@ -50,12 +54,14 @@ void Yaz_Proxy::recv_Z_PDU(Z_APDU *apdu) void Yaz_Proxy::failNotify() { + logf (LOG_LOG, "failNotity server"); delete m_client; delete this; } void Yaz_ProxyClient::failNotify() { + logf (LOG_LOG, "failNotity client"); delete m_server; delete this; } diff --git a/src/yaz-server.cpp b/src/yaz-server.cpp index 7d496c9..e72ed01 100644 --- a/src/yaz-server.cpp +++ b/src/yaz-server.cpp @@ -4,8 +4,12 @@ * Sebastian Hammer, Adam Dickmeiss * * $Log: yaz-server.cpp,v $ - * Revision 1.1 1999-01-28 09:41:07 adam - * Initial revision + * Revision 1.2 1999-01-28 13:08:47 adam + * Yaz_PDU_Assoc better encapsulated. Memory leak fix in + * yaz-socket-manager.cc. + * + * Revision 1.1.1.1 1999/01/28 09:41:07 adam + * First implementation of YAZ++. * */ @@ -19,6 +23,9 @@ public: MyServer(IYaz_PDU_Observable *the_PDU_Observable); void recv_Z_PDU(Z_APDU *apdu); IYaz_PDU_Observer* clone(IYaz_PDU_Observable *the_PDU_Observable); + void failNotify(); +private: + int m_no; }; static int stop = 0; @@ -49,24 +56,35 @@ void MyServer::recv_Z_PDU(Z_APDU *apdu) IYaz_PDU_Observer *MyServer::clone(IYaz_PDU_Observable *the_PDU_Observable) { + logf (LOG_LOG, "clone %d", m_no); + m_no++; return new MyServer(the_PDU_Observable); } MyServer::MyServer(IYaz_PDU_Observable *the_PDU_Observable) : Yaz_IR_Assoc (the_PDU_Observable) { + m_no = 0; +} +void MyServer::failNotify() +{ + delete this; } int main(int argc, char **argv) { Yaz_SocketManager mySocketManager; - Yaz_PDU_Assoc my_PDU_Assoc(&mySocketManager, 0); - MyServer z(&my_PDU_Assoc); - - z.server("@:9999"); - + MyServer z(new Yaz_PDU_Assoc(&mySocketManager, 0)); + + if (argc <= 1) + z.server("@:9999"); + else + { + for (int i = 1; i < argc; i++) + z.server(argv[i]); + } while (!stop && mySocketManager.processEvent() > 0) ; } diff --git a/src/yaz-socket-manager.cpp b/src/yaz-socket-manager.cpp index a1ebbc5..8f209ac 100644 --- a/src/yaz-socket-manager.cpp +++ b/src/yaz-socket-manager.cpp @@ -4,8 +4,12 @@ * Sebastian Hammer, Adam Dickmeiss * * $Log: yaz-socket-manager.cpp,v $ - * Revision 1.1 1999-01-28 09:41:07 adam - * Initial revision + * Revision 1.2 1999-01-28 13:08:48 adam + * Yaz_PDU_Assoc better encapsulated. Memory leak fix in + * yaz-socket-manager.cc. + * + * Revision 1.1.1.1 1999/01/28 09:41:07 adam + * First implementation of YAZ++. * */ #include @@ -99,6 +103,7 @@ int Yaz_SocketManager::processEvent() if (event) { event->observer->socketNotify(event->event); + delete event; return 1; } @@ -114,7 +119,7 @@ int Yaz_SocketManager::processEvent() FD_ZERO(&except); timeout = &to; /* hang on select */ - to.tv_sec = 5*60; + to.tv_sec = 60; to.tv_usec = 0; for (YazSocketEntry *p = m_observers; p; p = p->next) @@ -162,6 +167,7 @@ int Yaz_SocketManager::processEvent() if ((event = getEvent())) { event->observer->socketNotify(event->event); + delete event; return 1; } return 0; @@ -169,7 +175,6 @@ int Yaz_SocketManager::processEvent() void Yaz_SocketManager::putEvent(YazSocketEvent *event) { - logf (LOG_LOG, "putEvent p=%p event=%d", event, event->event); // put in back of queue if (m_queue_back) { -- 1.7.10.4