2 * Copyright (c) 1998-1999, Index Data.
3 * See the file LICENSE for details.
4 * Sebastian Hammer, Adam Dickmeiss
6 * $Log: yaz-socket-manager.cpp,v $
7 * Revision 1.8 1999-12-06 13:52:45 adam
8 * Modified for new location of YAZ header files. Experimental threaded
11 * Revision 1.7 1999/04/28 13:02:08 adam
12 * Added include of string.h.
14 * Revision 1.6 1999/04/21 12:09:01 adam
15 * Many improvements. Modified to proxy server to work with "sessions"
18 * Revision 1.5 1999/04/09 11:46:57 adam
19 * Added object Yaz_Z_Assoc. Much more functional client.
21 * Revision 1.4 1999/03/23 14:17:57 adam
22 * More work on timeout handling. Work on yaz-client.
24 * Revision 1.3 1999/02/02 14:01:23 adam
25 * First WIN32 port of YAZ++.
27 * Revision 1.2 1999/01/28 13:08:48 adam
28 * Yaz_PDU_Assoc better encapsulated. Memory leak fix in
29 * yaz-socket-manager.cc.
31 * Revision 1.1.1.1 1999/01/28 09:41:07 adam
32 * First implementation of YAZ++.
40 #include <sys/types.h>
47 #include <yaz-socket-manager.h>
50 Yaz_SocketManager::YazSocketEntry **Yaz_SocketManager::lookupObserver(
51 IYazSocketObserver *observer)
55 for (se = &m_observers; *se; se = &(*se)->next)
56 if ((*se)->observer == observer)
61 void Yaz_SocketManager::addObserver(int fd, IYazSocketObserver *observer)
65 se = *lookupObserver(observer);
68 se = new YazSocketEntry;
69 se->next= m_observers;
71 se->observer = observer;
75 se->last_activity = 0;
79 void Yaz_SocketManager::deleteObserver(IYazSocketObserver *observer)
81 YazSocketEntry **se = lookupObserver(observer);
84 removeEvent (observer);
85 YazSocketEntry *se_tmp = *se;
91 void Yaz_SocketManager::deleteObservers()
93 YazSocketEntry *se = m_observers;
97 YazSocketEntry *se_next = se->next;
104 void Yaz_SocketManager::maskObserver(IYazSocketObserver *observer, int mask)
108 se = *lookupObserver(observer);
113 void Yaz_SocketManager::timeoutObserver(IYazSocketObserver *observer,
118 se = *lookupObserver(observer);
120 se->timeout = timeout;
123 int Yaz_SocketManager::processEvent()
126 YazSocketEvent *event = getEvent();
127 unsigned timeout = 0;
128 logf (m_log, "processEvent");
131 event->observer->socketNotify(event->event);
136 fd_set in, out, except;
145 time_t now = time(0);
146 for (p = m_observers; p; p = p->next)
151 if (p->mask & YAZ_SOCKET_OBSERVE_READ)
153 if (p->mask & YAZ_SOCKET_OBSERVE_WRITE)
155 if (p->mask & YAZ_SOCKET_OBSERVE_EXCEPT)
161 unsigned timeout_this;
162 timeout_this = p->timeout;
163 if (p->last_activity)
164 timeout_this -= now - p->last_activity;
165 if (timeout_this < 1)
167 if (!timeout || timeout_this < timeout)
168 timeout = timeout_this;
173 logf (m_log, "no pending events return 0");
175 logf (m_log, "no observers");
183 logf (m_log, "select pending=%d timeout=%d", no, timeout);
184 while ((res = select(max + 1, &in, &out, &except, timeout ? &to : 0)) < 0)
188 for (p = m_observers; p; p = p->next)
192 if (FD_ISSET(fd, &in))
193 mask |= YAZ_SOCKET_OBSERVE_READ;
195 if (FD_ISSET(fd, &out))
196 mask |= YAZ_SOCKET_OBSERVE_WRITE;
198 if (FD_ISSET(fd, &except))
199 mask |= YAZ_SOCKET_OBSERVE_EXCEPT;
203 YazSocketEvent *event = new YazSocketEvent;
204 p->last_activity = now;
205 event->observer = p->observer;
209 else if (p->timeout && now >= p->last_activity + (int) (p->timeout))
211 YazSocketEvent *event = new YazSocketEvent;
212 p->last_activity = now;
213 event->observer = p->observer;
214 event->event = YAZ_SOCKET_OBSERVE_TIMEOUT;
218 if ((event = getEvent()))
220 event->observer->socketNotify(event->event);
227 void Yaz_SocketManager::putEvent(YazSocketEvent *event)
229 // put in back of queue
232 m_queue_back->prev = event;
233 assert (m_queue_front);
237 assert (!m_queue_front);
238 m_queue_front = event;
240 event->next = m_queue_back;
242 m_queue_back = event;
245 Yaz_SocketManager::YazSocketEvent *Yaz_SocketManager::getEvent()
247 // get from front of queue
248 YazSocketEvent *event = m_queue_front;
251 assert (m_queue_back);
252 m_queue_front = event->prev;
255 assert (m_queue_back);
256 m_queue_front->next = 0;
263 void Yaz_SocketManager::removeEvent(IYazSocketObserver *observer)
265 YazSocketEvent *ev = m_queue_back;
268 YazSocketEvent *ev_next = ev->next;
269 if (observer == ev->observer)
272 ev->prev->next = ev->next;
274 m_queue_back = ev->next;
276 ev->next->prev = ev->prev;
278 m_queue_front = ev->prev;
285 Yaz_SocketManager::Yaz_SocketManager()
293 Yaz_SocketManager::~Yaz_SocketManager()