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.5 1999-04-09 11:46:57 adam
8 * Added object Yaz_Z_Assoc. Much more functional client.
10 * Revision 1.4 1999/03/23 14:17:57 adam
11 * More work on timeout handling. Work on yaz-client.
13 * Revision 1.3 1999/02/02 14:01:23 adam
14 * First WIN32 port of YAZ++.
16 * Revision 1.2 1999/01/28 13:08:48 adam
17 * Yaz_PDU_Assoc better encapsulated. Memory leak fix in
18 * yaz-socket-manager.cc.
20 * Revision 1.1.1.1 1999/01/28 09:41:07 adam
21 * First implementation of YAZ++.
29 #include <sys/types.h>
35 #include <yaz-socket-manager.h>
38 Yaz_SocketManager::YazSocketEntry **Yaz_SocketManager::lookupObserver(
39 IYazSocketObserver *observer)
43 for (se = &m_observers; *se; se = &(*se)->next)
44 if ((*se)->observer == observer)
49 void Yaz_SocketManager::addObserver(int fd, IYazSocketObserver *observer)
53 se = *lookupObserver(observer);
56 se = new YazSocketEntry;
57 se->next= m_observers;
59 se->observer = observer;
63 se->last_activity = 0;
67 void Yaz_SocketManager::deleteObserver(IYazSocketObserver *observer)
69 YazSocketEntry **se = lookupObserver(observer);
72 removeEvent (observer);
73 YazSocketEntry *se_tmp = *se;
79 void Yaz_SocketManager::deleteObservers()
81 YazSocketEntry *se = m_observers;
85 YazSocketEntry *se_next = se->next;
92 void Yaz_SocketManager::maskObserver(IYazSocketObserver *observer, int mask)
96 se = *lookupObserver(observer);
101 void Yaz_SocketManager::timeoutObserver(IYazSocketObserver *observer,
106 se = *lookupObserver(observer);
108 se->timeout = timeout;
111 int Yaz_SocketManager::processEvent()
114 YazSocketEvent *event = getEvent();
115 unsigned timeout = 0;
116 logf (LOG_LOG, "processEvent");
119 event->observer->socketNotify(event->event);
124 fd_set in, out, except;
133 time_t now = time(0);
134 for (p = m_observers; p; p = p->next)
139 if (p->mask & YAZ_SOCKET_OBSERVE_READ)
141 if (p->mask & YAZ_SOCKET_OBSERVE_WRITE)
143 if (p->mask & YAZ_SOCKET_OBSERVE_EXCEPT)
149 unsigned timeout_this;
150 timeout_this = p->timeout;
151 if (p->last_activity)
152 timeout_this -= now - p->last_activity;
153 if (timeout_this < 1)
155 if (!timeout || timeout_this < timeout)
156 timeout = timeout_this;
161 logf (LOG_LOG, "no pending events return 0");
163 logf (LOG_LOG, "no observers");
171 while ((res = select(max + 1, &in, &out, &except, timeout ? &to : 0)) < 0)
175 for (p = m_observers; p; p = p->next)
179 if (FD_ISSET(fd, &in))
180 mask |= YAZ_SOCKET_OBSERVE_READ;
182 if (FD_ISSET(fd, &out))
183 mask |= YAZ_SOCKET_OBSERVE_WRITE;
185 if (FD_ISSET(fd, &except))
186 mask |= YAZ_SOCKET_OBSERVE_EXCEPT;
190 YazSocketEvent *event = new YazSocketEvent;
191 p->last_activity = now;
192 event->observer = p->observer;
196 else if (p->timeout && now >= p->last_activity + (int) (p->timeout))
198 YazSocketEvent *event = new YazSocketEvent;
199 p->last_activity = now;
200 event->observer = p->observer;
201 event->event = YAZ_SOCKET_OBSERVE_TIMEOUT;
205 if ((event = getEvent()))
207 event->observer->socketNotify(event->event);
214 void Yaz_SocketManager::putEvent(YazSocketEvent *event)
216 // put in back of queue
219 m_queue_back->prev = event;
220 assert (m_queue_front);
224 assert (!m_queue_front);
225 m_queue_front = event;
227 event->next = m_queue_back;
229 m_queue_back = event;
232 Yaz_SocketManager::YazSocketEvent *Yaz_SocketManager::getEvent()
234 // get from front of queue
235 YazSocketEvent *event = m_queue_front;
238 assert (m_queue_back);
239 m_queue_front = event->prev;
242 assert (m_queue_back);
243 m_queue_front->next = 0;
250 void Yaz_SocketManager::removeEvent(IYazSocketObserver *observer)
252 YazSocketEvent *ev = m_queue_back;
255 YazSocketEvent *ev_next = ev->next;
256 if (observer == ev->observer)
259 ev->prev->next = ev->next;
261 m_queue_back = ev->next;
263 ev->next->prev = ev->prev;
265 m_queue_front = ev->prev;
272 Yaz_SocketManager::Yaz_SocketManager()
279 Yaz_SocketManager::~Yaz_SocketManager()