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.7 1999-04-28 13:02:08 adam
8 * Added include of string.h.
10 * Revision 1.6 1999/04/21 12:09:01 adam
11 * Many improvements. Modified to proxy server to work with "sessions"
14 * Revision 1.5 1999/04/09 11:46:57 adam
15 * Added object Yaz_Z_Assoc. Much more functional client.
17 * Revision 1.4 1999/03/23 14:17:57 adam
18 * More work on timeout handling. Work on yaz-client.
20 * Revision 1.3 1999/02/02 14:01:23 adam
21 * First WIN32 port of YAZ++.
23 * Revision 1.2 1999/01/28 13:08:48 adam
24 * Yaz_PDU_Assoc better encapsulated. Memory leak fix in
25 * yaz-socket-manager.cc.
27 * Revision 1.1.1.1 1999/01/28 09:41:07 adam
28 * First implementation of YAZ++.
36 #include <sys/types.h>
43 #include <yaz-socket-manager.h>
46 Yaz_SocketManager::YazSocketEntry **Yaz_SocketManager::lookupObserver(
47 IYazSocketObserver *observer)
51 for (se = &m_observers; *se; se = &(*se)->next)
52 if ((*se)->observer == observer)
57 void Yaz_SocketManager::addObserver(int fd, IYazSocketObserver *observer)
61 se = *lookupObserver(observer);
64 se = new YazSocketEntry;
65 se->next= m_observers;
67 se->observer = observer;
71 se->last_activity = 0;
75 void Yaz_SocketManager::deleteObserver(IYazSocketObserver *observer)
77 YazSocketEntry **se = lookupObserver(observer);
80 removeEvent (observer);
81 YazSocketEntry *se_tmp = *se;
87 void Yaz_SocketManager::deleteObservers()
89 YazSocketEntry *se = m_observers;
93 YazSocketEntry *se_next = se->next;
100 void Yaz_SocketManager::maskObserver(IYazSocketObserver *observer, int mask)
104 se = *lookupObserver(observer);
109 void Yaz_SocketManager::timeoutObserver(IYazSocketObserver *observer,
114 se = *lookupObserver(observer);
116 se->timeout = timeout;
119 int Yaz_SocketManager::processEvent()
122 YazSocketEvent *event = getEvent();
123 unsigned timeout = 0;
124 logf (LOG_LOG, "processEvent");
127 event->observer->socketNotify(event->event);
132 fd_set in, out, except;
141 time_t now = time(0);
142 for (p = m_observers; p; p = p->next)
147 if (p->mask & YAZ_SOCKET_OBSERVE_READ)
149 if (p->mask & YAZ_SOCKET_OBSERVE_WRITE)
151 if (p->mask & YAZ_SOCKET_OBSERVE_EXCEPT)
157 unsigned timeout_this;
158 timeout_this = p->timeout;
159 if (p->last_activity)
160 timeout_this -= now - p->last_activity;
161 if (timeout_this < 1)
163 if (!timeout || timeout_this < timeout)
164 timeout = timeout_this;
169 logf (LOG_LOG, "no pending events return 0");
171 logf (LOG_LOG, "no observers");
179 logf (LOG_LOG, "timeout=%d", timeout);
180 while ((res = select(max + 1, &in, &out, &except, timeout ? &to : 0)) < 0)
184 for (p = m_observers; p; p = p->next)
188 if (FD_ISSET(fd, &in))
189 mask |= YAZ_SOCKET_OBSERVE_READ;
191 if (FD_ISSET(fd, &out))
192 mask |= YAZ_SOCKET_OBSERVE_WRITE;
194 if (FD_ISSET(fd, &except))
195 mask |= YAZ_SOCKET_OBSERVE_EXCEPT;
199 YazSocketEvent *event = new YazSocketEvent;
200 p->last_activity = now;
201 event->observer = p->observer;
205 else if (p->timeout && now >= p->last_activity + (int) (p->timeout))
207 YazSocketEvent *event = new YazSocketEvent;
208 p->last_activity = now;
209 event->observer = p->observer;
210 event->event = YAZ_SOCKET_OBSERVE_TIMEOUT;
214 if ((event = getEvent()))
216 event->observer->socketNotify(event->event);
223 void Yaz_SocketManager::putEvent(YazSocketEvent *event)
225 // put in back of queue
228 m_queue_back->prev = event;
229 assert (m_queue_front);
233 assert (!m_queue_front);
234 m_queue_front = event;
236 event->next = m_queue_back;
238 m_queue_back = event;
241 Yaz_SocketManager::YazSocketEvent *Yaz_SocketManager::getEvent()
243 // get from front of queue
244 YazSocketEvent *event = m_queue_front;
247 assert (m_queue_back);
248 m_queue_front = event->prev;
251 assert (m_queue_back);
252 m_queue_front->next = 0;
259 void Yaz_SocketManager::removeEvent(IYazSocketObserver *observer)
261 YazSocketEvent *ev = m_queue_back;
264 YazSocketEvent *ev_next = ev->next;
265 if (observer == ev->observer)
268 ev->prev->next = ev->next;
270 m_queue_back = ev->next;
272 ev->next->prev = ev->prev;
274 m_queue_front = ev->prev;
281 Yaz_SocketManager::Yaz_SocketManager()
288 Yaz_SocketManager::~Yaz_SocketManager()