File indexing completed on 2025-01-05 04:37:19

0001 /*
0002     SPDX-FileCopyrightText: 2010 Joris Guisson <joris.guisson@gmail.com>
0003 
0004     SPDX-License-Identifier: GPL-2.0-or-later
0005 */
0006 
0007 #include "poll.h"
0008 #include <util/log.h>
0009 
0010 #ifndef Q_WS_WIN
0011 #include <sys/poll.h>
0012 #else
0013 #include <util/win32.h>
0014 #endif
0015 
0016 using namespace bt;
0017 
0018 namespace net
0019 {
0020 Poll::Poll()
0021     : num_sockets(0)
0022 {
0023 }
0024 
0025 Poll::~Poll()
0026 {
0027 }
0028 
0029 int Poll::add(int fd, Poll::Mode mode)
0030 {
0031     if (fd_vec.size() <= num_sockets) {
0032         // expand pollfd vector if necessary
0033         struct pollfd pfd;
0034         pfd.fd = fd;
0035         pfd.revents = 0;
0036         pfd.events = mode == INPUT ? POLLIN : POLLOUT;
0037         fd_vec.push_back(pfd);
0038     } else {
0039         // use existing slot
0040         struct pollfd &pfd = fd_vec[num_sockets];
0041         pfd.fd = fd;
0042         pfd.revents = 0;
0043         pfd.events = mode == INPUT ? POLLIN : POLLOUT;
0044     }
0045 
0046     int ret = num_sockets;
0047     num_sockets++;
0048     return ret;
0049 }
0050 
0051 int Poll::add(PollClient::Ptr pc)
0052 {
0053     int idx = add(pc->fd(), INPUT);
0054     poll_clients[idx] = pc;
0055     return idx;
0056 }
0057 
0058 bool Poll::ready(int index, Poll::Mode mode) const
0059 {
0060     if (index < 0 || index >= (int)num_sockets)
0061         return false;
0062 
0063     return fd_vec[index].revents & (mode == INPUT ? POLLIN : POLLOUT);
0064 }
0065 
0066 void Poll::reset()
0067 {
0068     num_sockets = 0;
0069 }
0070 
0071 int Poll::poll(int timeout)
0072 {
0073     if (num_sockets == 0)
0074         return 0;
0075 
0076     int ret = 0;
0077 #ifndef Q_WS_WIN
0078     ret = ::poll(&fd_vec[0], num_sockets, timeout);
0079 #else
0080     ret = ::mingw_poll(&fd_vec[0], num_sockets, timeout);
0081 #endif
0082 
0083     std::map<int, PollClient::Ptr>::iterator itr = poll_clients.begin();
0084     while (itr != poll_clients.end()) {
0085         if (ret > 0 && ready(itr->first, INPUT))
0086             itr->second->handleData();
0087         itr->second->reset();
0088         ++itr;
0089     }
0090 
0091     poll_clients.clear();
0092     return ret;
0093 }
0094 
0095 }