X-Git-Url: http://sru.miketaylor.org.uk/?a=blobdiff_plain;f=src%2Fyaz-pdu-assoc.cpp;h=c7475fce02acacf86c02c7a0ade9328881917a80;hb=e08f9ff89133cbc295dda92b9c863ddd288569d1;hp=6056b2d81f2a02004ea798b7080560e4e1c70792;hpb=bf377ba45c8c1cbcf843fdecc6d5c68fda6bad18;p=yazpp-moved-to-github.git diff --git a/src/yaz-pdu-assoc.cpp b/src/yaz-pdu-assoc.cpp index 6056b2d..c7475fc 100644 --- a/src/yaz-pdu-assoc.cpp +++ b/src/yaz-pdu-assoc.cpp @@ -4,8 +4,32 @@ * Sebastian Hammer, Adam Dickmeiss * * $Log: yaz-pdu-assoc.cpp,v $ - * Revision 1.1 1999-01-28 09:41:07 adam - * Initial revision + * Revision 1.8 1999-04-28 13:04:03 adam + * Fixed setting of proxy otherInfo so that database(s) are removed. + * + * Revision 1.7 1999/04/21 12:09:01 adam + * Many improvements. Modified to proxy server to work with "sessions" + * based on cookies. + * + * Revision 1.6 1999/04/20 10:30:05 adam + * Implemented various stuff for client and proxy. Updated calls + * to ODR to reflect new name parameter. + * + * Revision 1.5 1999/04/09 11:46:57 adam + * Added object Yaz_Z_Assoc. Much more functional client. + * + * Revision 1.4 1999/03/23 14:17:57 adam + * More work on timeout handling. Work on yaz-client. + * + * Revision 1.3 1999/02/02 14:01:20 adam + * First WIN32 port of YAZ++. + * + * 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 +53,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,36 +64,12 @@ 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) { - logf (LOG_LOG, "socketNotify p=%p event = %d", this, event); + logf (LOG_LOG, "Yaz_PDU_Assoc::socketNotify p=%p event = %d", this, event); if (m_state == Connected) { m_state = Ready; @@ -95,7 +96,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; @@ -123,18 +123,18 @@ void Yaz_PDU_Assoc::socketNotify(int event) assoc->m_socketObservable->maskObserver(assoc, YAZ_SOCKET_OBSERVE_READ| YAZ_SOCKET_OBSERVE_EXCEPT); + assoc->m_socketObservable->timeoutObserver(assoc, + assoc->m_idleTime); } } else if (m_state == Ready) { 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 +142,23 @@ 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)); + } + if (event & YAZ_SOCKET_OBSERVE_TIMEOUT) + { + m_PDU_Observer->timeoutNotify(); } } } @@ -163,18 +173,46 @@ void Yaz_PDU_Assoc::close() cs_close (m_cs); } m_cs = 0; - PDU_Queue **q = &m_queue_out; - while (*q) + while (m_queue_out) { - PDU_Queue *q_this = *q; - *q = (*q)->m_next; + PDU_Queue *q_this = m_queue_out; + m_queue_out = m_queue_out->m_next; delete q_this; } - free (m_input_buf); +// free (m_input_buf); m_input_buf = 0; 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); @@ -191,10 +229,12 @@ Yaz_PDU_Assoc::PDU_Queue::~PDU_Queue() int Yaz_PDU_Assoc::flush_PDU() { int r; - - logf (LOG_LOG, "flush_PDU fd=%d", cs_fileno(m_cs)); + + logf (LOG_LOG, "Yaz_PDU_Assoc::flush_PDU"); if (m_state != Ready) + { return 1; + } PDU_Queue *q = m_queue_out; if (!q) { @@ -214,13 +254,13 @@ int Yaz_PDU_Assoc::flush_PDU() m_socketObservable->maskObserver(this, YAZ_SOCKET_OBSERVE_READ| YAZ_SOCKET_OBSERVE_EXCEPT| YAZ_SOCKET_OBSERVE_WRITE); - logf (LOG_LOG, "put %d bytes (incomplete write)", q->m_len); + logf (LOG_LOG, "Yaz_PDU_Assoc::flush_PDU put %d bytes (incomplete)", + q->m_len); return r; } - logf (LOG_LOG, "put %d bytes fd=%d", q->m_len, cs_fileno(m_cs)); + logf (LOG_LOG, "Yaz_PDU_Assoc::flush_PDU put %d bytes", q->m_len); // whole packet sent... delete this and proceed to next ... m_queue_out = q->m_next; - logf (LOG_LOG, "m_queue_out = %p", m_queue_out); delete q; // don't select on write if queue is empty ... if (!m_queue_out) @@ -231,27 +271,23 @@ int Yaz_PDU_Assoc::flush_PDU() int Yaz_PDU_Assoc::send_PDU(const char *buf, int len) { + logf (LOG_LOG, "Yaz_PDU_Assoc::send_PDU"); 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"); - return 0; + logf (LOG_LOG, "Yaz_PDU_Assoc::send_PDU failed, m_cs == 0"); + return -1; } while (*pq) pq = &(*pq)->m_next; *pq = new PDU_Queue(buf, len); if (is_idle) - { return flush_PDU (); - } else - { - logf (LOG_LOG, "cannot send_PDU fd=%d", cs_fileno(m_cs)); - } + logf (LOG_LOG, "Yaz_PDU_Assoc::cannot send_PDU fd=%d", + cs_fileno(m_cs)); return 0; } @@ -273,6 +309,7 @@ void Yaz_PDU_Assoc::listen(IYaz_PDU_Observer *observer, void *ap; COMSTACK cs = comstack(); + logf (LOG_LOG, "Yaz_PDU_Assoc::listen %s", addr); m_PDU_Observer = observer; if (!cs) return; @@ -287,29 +324,57 @@ void Yaz_PDU_Assoc::listen(IYaz_PDU_Observer *observer, m_state = Listen; } +void Yaz_PDU_Assoc::idleTime(int idleTime) +{ + m_idleTime = idleTime; + logf (LOG_LOG, "Yaz_PDU_Assoc::idleTime(%d)", idleTime); + m_socketObservable->timeoutObserver(this, m_idleTime); +} + void Yaz_PDU_Assoc::connect(IYaz_PDU_Observer *observer, const char *addr) { - logf (LOG_LOG, "Yaz_PDU_Assoc::connect"); + logf (LOG_LOG, "Yaz_PDU_Assoc::connect %s", addr); close(); m_PDU_Observer = observer; COMSTACK cs = comstack(); void *ap = cs_straddr (cs, addr); if (!ap) - return; + { + logf (LOG_LOG, "cs_straddr failed"); + return; + } int res = cs_connect (cs, ap); if (res < 0) { - logf (LOG_DEBUG, "Yaz_PDU_Assoc::connect failed"); + logf (LOG_LOG|LOG_ERRNO, "Yaz_PDU_Assoc::connect failed"); +#if 1 + 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); + m_state = Connecting; +#else close (); - return; +#endif } - 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) + { + logf (LOG_LOG, "Yaz_PDU_Assoc::connect pending"); + m_state = Connecting; + } + else + { + logf (LOG_LOG, "Yaz_PDU_Assoc::Connect complete"); + m_state = Connected; + } + } }