Mercurial > code
view C++/SocketListener.cpp @ 247:806dbb6011c7
Socket:
* Make copyable so it's easier to use with SocketListener
* Remove domain(), type() and protocol() functions because accept() can not determine them
author | David Demelier <markand@malikania.fr> |
---|---|
date | Tue, 30 Sep 2014 20:44:50 +0200 |
parents | 3c12f0e8bbb9 |
children | 4ad3c85ab73e |
line wrap: on
line source
/* * SocketListener.cpp -- portable select() wrapper * * Copyright (c) 2013, David Demelier <markand@malikania.fr> * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include <algorithm> #include "SocketListener.h" const char *SocketTimeout::what() const noexcept { return "Timeout occured"; } SocketListener::SocketListener(int count) { m_sockets.reserve(count); } void SocketListener::add(Socket s) { m_sockets.push_back(std::move(s)); } void SocketListener::remove(const Socket &s) { m_sockets.erase(std::remove(m_sockets.begin(), m_sockets.end(), s), m_sockets.end()); } void SocketListener::clear() { m_sockets.clear(); } unsigned SocketListener::size() { return m_sockets.size(); } Socket &SocketListener::select(int s, int us) { fd_set fds; timeval maxwait, *towait; auto fdmax = m_sockets.front().handle(); FD_ZERO(&fds); for (auto &c : m_sockets) { FD_SET(c.handle(), &fds); if ((int)c.handle() > fdmax) fdmax = c.handle(); } maxwait.tv_sec = s; maxwait.tv_usec = us; // Set to NULL for infinite timeout. towait = (s == 0 && us == 0) ? nullptr : &maxwait; auto error = ::select(fdmax + 1, &fds, NULL, NULL, towait); if (error == SOCKET_ERROR) throw SocketError(Socket::syserror()); if (error == 0) throw SocketTimeout(); for (Socket &c : m_sockets) if (FD_ISSET(c.handle(), &fds)) return c; throw SocketError("No socket found"); }