BlinkenArea - GitList
Repositories
Blog
Wiki
Blinker
Code
Commits
Branches
Tags
Search
Tree:
362c1f4
Branches
Tags
master
Blinker
src
windows
Io.cpp
update copyright header
Stefan Schuermans
commited
362c1f4
at 2019-05-04 17:17:10
Io.cpp
Blame
History
Raw
/* Blinker Copyright 2011-2019 Stefan Schuermans <stefan@blinkenarea.org> Copyleft GNU public license - http://www.gnu.org/copyleft/gpl.html a blinkenarea.org project */ #include <winsock2.h> #include <set> #include "Io.h" #include "Time.h" namespace Blinker { /** * @brief wait for I/O events * @param[in] read I/O objects to check for readability * @param[out] read I/O objects that are readable * @param[in] write I/O objects to check for writability * @param[out] write I/O objects that are writable * @param[in] timeout maximum time to wait */ void Io::wait(Set &read, Set &write, const Time &timeout) { static const Time maxTimeout(1); // maximum timeout for I/O wait // get read set and write set, also count entries unsigned int rds = 0; fd_set fd_rd; FD_ZERO(&fd_rd); for (Set::const_iterator it = read.begin(); it != read.end(); ++it) { if ((*it)->m_socket != INVALID_SOCKET) { FD_SET((*it)->m_socket, &fd_rd); ++rds; } } unsigned int wrs = 0; fd_set fd_wr; FD_ZERO(&fd_wr); for (Set::const_iterator it = write.begin(); it != write.end(); ++it) { if ((*it)->m_socket != INVALID_SOCKET) { FD_SET((*it)->m_socket, &fd_wr); ++wrs; } } /* special case for no sockets to check, because select does not work for allsets empty on Windows */ if (rds == 0 && wrs == 0) { if (timeout <= Time::zero) { return; } Sleep(timeout.toMs()); } // get timeout struct timeval to; if (timeout < Time::zero) { // don't use negative timeout Time::zero.toTimeval(to); } else if (timeout > maxTimeout) { // stay responsive -> no more than max maxTimeout.toTimeval(to); } else { timeout.toTimeval(to); } // wait for I/O event on sockets fd_set fd_err; FD_ZERO(&fd_err); int res = select(0 /* ignored on Windows */, &fd_rd, &fd_wr, &fd_err, &to); // error or timeout if (res <= 0) { // return with empty sets read.clear(); write.clear(); return; } // remove file descriptors without event pending from sets Set::iterator it; it = read.begin(); while (it != read.end()) { if ((*it)->m_socket != INVALID_SOCKET && FD_ISSET((*it)->m_socket, &fd_rd)) { ++it; } else { Set::iterator del = it; ++it; read.erase(del); } } // while it it = write.begin(); while (it != write.end()) { if ((*it)->m_socket != INVALID_SOCKET && FD_ISSET((*it)->m_socket, &fd_wr)) { ++it; } else { Set::iterator del = it; ++it; write.erase(del); } } // while it } /// constructor Io::Io(): m_socket(INVALID_SOCKET) { } } // namespace Blinker