2 * Copyright (c) 1998-2001, Index Data.
3 * See the file LICENSE for details.
5 * $Id: yaz-socket-manager.cpp,v 1.19 2002-10-09 12:50:26 adam Exp $
12 #include <sys/types.h>
19 #include <yaz++/socket-manager.h>
21 Yaz_SocketManager::YazSocketEntry **Yaz_SocketManager::lookupObserver(
22 IYazSocketObserver *observer)
26 for (se = &m_observers; *se; se = &(*se)->next)
27 if ((*se)->observer == observer)
32 void Yaz_SocketManager::addObserver(int fd, IYazSocketObserver *observer)
36 se = *lookupObserver(observer);
39 se = new YazSocketEntry;
40 se->next= m_observers;
42 se->observer = observer;
46 se->last_activity = 0;
50 void Yaz_SocketManager::deleteObserver(IYazSocketObserver *observer)
52 YazSocketEntry **se = lookupObserver(observer);
55 removeEvent (observer);
56 YazSocketEntry *se_tmp = *se;
62 void Yaz_SocketManager::deleteObservers()
64 YazSocketEntry *se = m_observers;
68 YazSocketEntry *se_next = se->next;
75 void Yaz_SocketManager::maskObserver(IYazSocketObserver *observer, int mask)
79 se = *lookupObserver(observer);
84 void Yaz_SocketManager::timeoutObserver(IYazSocketObserver *observer,
89 se = *lookupObserver(observer);
91 se->timeout = timeout;
94 int Yaz_SocketManager::processEvent()
97 YazSocketEvent *event = getEvent();
99 yaz_log (m_log, "Yaz_SocketManager::processEvent manager=%p", this);
102 event->observer->socketNotify(event->event);
107 fd_set in, out, except;
116 time_t now = time(0);
117 for (p = m_observers; p; p = p->next)
122 if (p->mask & YAZ_SOCKET_OBSERVE_READ)
124 yaz_log (m_log, "Yaz_SocketManager::select fd=%d read", fd);
127 if (p->mask & YAZ_SOCKET_OBSERVE_WRITE)
129 yaz_log (m_log, "Yaz_SocketManager::select fd=%d write", fd);
132 if (p->mask & YAZ_SOCKET_OBSERVE_EXCEPT)
134 yaz_log (m_log, "Yaz_SocketManager::select fd=%d except", fd);
141 unsigned timeout_this;
142 timeout_this = p->timeout;
143 if (p->last_activity)
144 timeout_this -= now - p->last_activity;
146 p->last_activity = now;
147 if (timeout_this < 1 || timeout_this > 2147483646)
149 if (!timeout || timeout_this < timeout)
150 timeout = timeout_this;
151 p->timeout_this = timeout_this;
152 yaz_log (m_log, "Yaz_SocketManager::select timeout_this=%d",
158 yaz_log (m_log, "no pending events return 0");
160 yaz_log (m_log, "no observers");
168 yaz_log (m_log, "Yaz_SocketManager::select begin no=%d timeout=%d",
170 while ((res = select(max + 1, &in, &out, &except, timeout ? &to : 0)) < 0)
173 yaz_log (LOG_LOG|LOG_WARN, "select");
177 for (p = m_observers; p; p = p->next)
181 if (FD_ISSET(fd, &in))
182 mask |= YAZ_SOCKET_OBSERVE_READ;
184 if (FD_ISSET(fd, &out))
185 mask |= YAZ_SOCKET_OBSERVE_WRITE;
187 if (FD_ISSET(fd, &except))
188 mask |= YAZ_SOCKET_OBSERVE_EXCEPT;
192 YazSocketEvent *event = new YazSocketEvent;
193 p->last_activity = now;
194 event->observer = p->observer;
198 else if (res == 0 && p->timeout && p->timeout_this == timeout)
200 YazSocketEvent *event = new YazSocketEvent;
201 assert (p->last_activity);
202 yaz_log (m_log, "timeout, now = %ld last_activity=%ld timeout=%d",
203 now, p->last_activity, p->timeout);
204 p->last_activity = now;
205 event->observer = p->observer;
206 event->event = YAZ_SOCKET_OBSERVE_TIMEOUT;
210 if ((event = getEvent()))
212 event->observer->socketNotify(event->event);
216 yaz_log (LOG_WARN, "unhandled event in processEvent");
221 // n p n p ...... n p n p
224 void Yaz_SocketManager::putEvent(YazSocketEvent *event)
226 // put in back of queue
229 m_queue_back->prev = event;
230 assert (m_queue_front);
234 assert (!m_queue_front);
235 m_queue_front = event;
237 event->next = m_queue_back;
239 m_queue_back = event;
242 Yaz_SocketManager::YazSocketEvent *Yaz_SocketManager::getEvent()
244 // get from front of queue
245 YazSocketEvent *event = m_queue_front;
248 assert (m_queue_back);
249 m_queue_front = event->prev;
252 assert (m_queue_back);
253 m_queue_front->next = 0;
260 void Yaz_SocketManager::removeEvent(IYazSocketObserver *observer)
262 YazSocketEvent *ev = m_queue_back;
265 YazSocketEvent *ev_next = ev->next;
266 if (observer == ev->observer)
269 ev->prev->next = ev->next;
271 m_queue_back = ev->next;
273 ev->next->prev = ev->prev;
275 m_queue_front = ev->prev;
282 Yaz_SocketManager::Yaz_SocketManager()
290 Yaz_SocketManager::~Yaz_SocketManager()