39 #include "blocxx/BLOCXX_config.h" 47 #if defined(BLOCXX_WIN32) 55 #ifdef BLOCXX_HAVE_SYS_EPOLL_H 56 #include <sys/epoll.h> 58 #if defined (BLOCXX_HAVE_SYS_POLL_H) 61 #if defined (BLOCXX_HAVE_SYS_SELECT_H) 62 #include <sys/select.h> 66 #ifdef BLOCXX_HAVE_SYS_TIME_H 70 #include <sys/types.h> 72 #ifdef BLOCXX_HAVE_UNISTD_H 87 const float LOOP_TIMEOUT = 10.0;
97 #if defined(BLOCXX_WIN32) 103 size_t hcount =
static_cast<DWORD
>(selarray.
size());
106 size_t handleidx = 0;
107 for (
size_t i = 0;
i < selarray.
size();
i++, handleidx++)
109 if(selarray[
i].s.isSocket && selarray[
i].s.networkevents)
111 ::WSAEventSelect(selarray[i].s.sockfd,
112 selarray[i].s.event, selarray[i].s.networkevents);
115 hdls[handleidx] = selarray[
i].s.event;
120 DWORD cc = ::WaitForMultipleObjects(hcount, hdls.
get(), FALSE, timer.asDWORDMs());
122 assert(cc != WAIT_ABANDONED);
133 rc = cc - WAIT_OBJECT_0;
137 if(selarray[rc].s.isSocket)
139 if(selarray[rc].s.networkevents
140 && selarray[rc].s.doreset ==
false)
142 ::WSAEventSelect(selarray[rc].s.sockfd,
143 selarray[rc].s.event, selarray[rc].s.networkevents);
148 ::WSAEventSelect(selarray[rc].s.sockfd,
149 selarray[rc].s.event, 0);
151 ::ioctlsocket(selarray[rc].s.sockfd, FIONBIO, &ioctlarg);
160 int availableCount = 0;
161 for (
size_t i = 0;
i < selarray.
size();
i++)
163 if( WaitForSingleObject(selarray[
i].s.event, 0) == WAIT_OBJECT_0 )
165 if( selarray[i].waitForRead )
166 selarray[
i].readAvailable =
true;
167 if( selarray[i].waitForWrite )
168 selarray[
i].writeAvailable =
true;
173 selarray[
i].readAvailable =
false;
174 selarray[
i].writeAvailable =
false;
177 return availableCount;
188 #ifdef BLOCXX_HAVE_SYS_EPOLL_H 202 UInt32
const read_events = EPOLLIN | EPOLLPRI | EPOLLERR | EPOLLHUP;
203 UInt32
const write_events = EPOLLOUT | EPOLLERR | EPOLLHUP;
204 for (
size_t i = 0;
i < selarray.
size();
i++)
207 selarray[
i].readAvailable =
false;
208 selarray[
i].writeAvailable =
false;
209 selarray[
i].wasError =
false;
210 events[
i].data = epoll_data_t();
211 events[
i].data.u32 =
i;
212 events[
i].events = 0;
213 if(selarray[
i].waitForRead)
215 events[
i].events |= read_events;
217 if(selarray[
i].waitForWrite)
219 events[
i].events |= write_events;
222 if(epoll_ctl(epfd.
get(), EPOLL_CTL_ADD, selarray[
i].s, &events[
i]) != 0)
236 const float maxWaitSec = LOOP_TIMEOUT;
237 ecc = epoll_wait(epfd.
get(), events.get(), selarray.
size(), timer.
asIntMs(maxWaitSec));
239 if (ecc < 0 && errno == EINTR)
246 }
while ((ecc == 0) && !timer.
expired());
258 for(
int i = 0;
i < ecc;
i++)
276 #if defined (BLOCXX_HAVE_SYS_POLL_H) 288 for (
size_t i = 0;
i < selarray.
size();
i++)
291 selarray[
i].readAvailable =
false;
292 selarray[
i].writeAvailable =
false;
293 selarray[
i].wasError =
false;
295 pfds[
i].fd = selarray[
i].s;
296 pfds[
i].events = selarray[
i].waitForRead ? (POLLIN | POLLPRI) : 0;
297 if(selarray[
i].waitForWrite)
298 pfds[
i].events |= POLLOUT;
302 const float maxWaitSec = LOOP_TIMEOUT;
303 rc = ::poll(pfds.get(), selarray.
size(), timer.asIntMs(maxWaitSec));
305 if (rc < 0 && errno == EINTR)
310 #ifdef BLOCXX_NETWARE 320 }
while ((rc == 0) && !timer.expired());
331 for (
size_t i = 0;
i < selarray.
size();
i++)
333 if (pfds[
i].revents & (POLLERR | POLLNVAL))
335 selarray[
i].wasError =
true;
338 if(selarray[
i].waitForRead)
340 selarray[
i].readAvailable = (pfds[
i].revents &
341 (POLLIN | POLLPRI | POLLHUP));
344 if(selarray[
i].waitForWrite)
346 selarray[
i].writeAvailable = (pfds[
i].revents &
347 (POLLOUT | POLLHUP));
361 #if defined (BLOCXX_HAVE_SYS_SELECT_H) 376 for (
size_t i = 0;
i < selarray.
size(); ++
i)
378 int fd = selarray[
i].s;
384 if (fd < 0 || fd >= FD_SETSIZE)
389 if (selarray[
i].waitForRead)
393 if (selarray[
i].waitForWrite)
401 const float maxWaitSec = LOOP_TIMEOUT;
402 rc =
::select(maxfd+1, &ifds, &ofds, NULL, timer.asTimeval(tv, maxWaitSec));
404 if (rc < 0 && errno == EINTR)
409 #ifdef BLOCXX_NETWARE 419 }
while ((rc == 0) && !timer.
expired());
430 int availableCount = 0;
432 for (
size_t i = 0;
i < selarray.
size();
i++)
434 selarray[
i].wasError =
false;
436 if (FD_ISSET(selarray[
i].s, &ifds))
438 selarray[
i].readAvailable =
true;
443 selarray[
i].readAvailable =
false;
446 if (FD_ISSET(selarray[
i].s, &ofds))
448 selarray[
i].writeAvailable =
true;
453 selarray[
i].writeAvailable =
false;
456 availableCount += cval;
460 return availableCount;
487 #endif // #else BLOCXX_WIN32 501 for (
size_t i = 0;
i < selarray.
size(); ++
i)
514 for (
size_t i = 0;
i < soa.
size(); ++
i)
516 if (soa[
i].readAvailable)
Array<> wraps std::vector<> in COWReference<> adding ref counting and copy on write capability...
A TimeoutTimer is used by an algorithm to determine when a timeout has expired.
int selectRWPoll(SelectObjectArray &selarray, const Timeout &timeout)
void loop()
Meant to be called by timeout functions which loop, but don't want to reset the interval.
bool waitForWrite
Input parameter. Set it to true to indicate that waiting for write availability on s is desired...
#define BLOCXX_ASSERT(CON)
BLOCXX_ASSERT works similar to the assert() macro, but instead of calling abort(), it throws an AssertionException.
int select(const SelectTypeArray &selarray, UInt32 ms)
Select returns as soon as input is available on any of Select_t objects that are in given array...
bool expired() const
Indicates whether the last loop time has exceeded the timeout.
void reserve(size_type n)
Ensure the capacity is at least the size of a given value.
static Timeout relative(float seconds)
const int SELECT_ERROR
The value returned from select when any error occurs other than timeout.
int selectRWSelect(SelectObjectArray &selarray, const Timeout &timeout)
const int SELECT_TIMEOUT
The value returned from select when the timeout value has expired.
A timeout can be absolute, which means that it will happen at the specified DateTime.
PURPOSE: The AutoResource class template is an analog of std::auto_ptr for managing arbitrary resourc...
bool writeAvailable
Ouput parameter. Will be set to true to indicate that s has become available for writing.
void start()
Meant to be called by timeout functions which loop.
bool waitForRead
Input parameter. Set it to true to indicate that waiting for read availability on s is desired...
bool readAvailable
Ouput parameter. Will be set to true to indicate that s has become available for reading.
void push_back(const T &x)
Append an element to the end of the Array.
The AutoPtrVec class provides a simple class for smart pointers to a dynamically allocated array of o...
int selectRW(SelectObjectArray &selarray, UInt32 ms)
static void testCancel()
Test if this thread has been cancelled.
int selectRWEpoll(SelectObjectArray &selarray, const Timeout &timeout)
const int SELECT_NOT_IMPLEMENTED
Used internally, but listed here to prevent conflicts.