diff --git a/configure.ac b/configure.ac index 589f43f5..36496306 100644 --- a/configure.ac +++ b/configure.ac @@ -10,11 +10,15 @@ AC_CHECK_HEADERS([arpa/inet.h \ poll.h \ pthread.h \ sys/ioctl.h \ + sys/select.h \ termios.h]) AC_CHECK_LIB([pthread], [pthread_setname_np], - AC_DEFINE([HAVE_PTHREAD_SETNAME_NP], [1], ["Define to 1 if pthread has pthread_setname_np"]), - AC_MSG_RESULT([Could not find pthread_setname_np in pthread])) + AC_DEFINE([HAVE_PTHREAD_SETNAME_NP], [1], ["Define to 1 if pthread has pthread_setname_np."]), + AC_MSG_RESULT([Could not find pthread_setname_np in pthread.])) + +AC_CHECK_FUNC([pselect], [AC_DEFINE(HAVE_PSELECT, [1], [Define to 1 if pselect() is available.])]) +AC_CHECK_FUNC([ppoll], [AC_DEFINE(HAVE_PPOLL, [1], [Define to 1 if ppoll() is available.])]) AC_CONFIG_AUX_DIR([build]) AC_CONFIG_SRCDIR([src/ebusd/ebusd.cpp]) diff --git a/src/ebusd/network.cpp b/src/ebusd/network.cpp index 99dd0092..f9f99030 100644 --- a/src/ebusd/network.cpp +++ b/src/ebusd/network.cpp @@ -17,11 +17,19 @@ * along with ebusd. If not, see http://www.gnu.org/licenses/. */ +#ifdef HAVE_CONFIG_H +#include +#endif + #include "network.h" #include "logger.h" #include "appl.h" #include + +#ifdef HAVE_PPOLL #include +#endif + extern Logger& L; extern Appl& A; @@ -32,14 +40,17 @@ void* Connection::run() { m_running = true; - int ret, nfds = 2; - struct pollfd fds[nfds]; + int ret; struct timespec tdiff; // set select timeout 10 secs tdiff.tv_sec = 10; tdiff.tv_nsec = 0; +#ifdef HAVE_PPOLL + int nfds = 2; + struct pollfd fds[nfds]; + memset(fds, 0, sizeof(fds)); fds[0].fd = m_notify.notifyFD(); @@ -47,21 +58,55 @@ void* Connection::run() fds[1].fd = m_socket->getFD(); fds[1].events = POLLIN; +#else +#ifdef HAVE_PSELECT + int maxfd; + fd_set checkfds; + + FD_ZERO(&checkfds); + FD_SET(m_notify.notifyFD(), &checkfds); + FD_SET(m_socket->getFD(), &checkfds); + + (m_notify.notifyFD() > m_socket->getFD()) ? + (maxfd = m_notify.notifyFD()) : (maxfd = m_socket->getFD()); +#endif +#endif for (;;) { + +#ifdef HAVE_PPOLL // wait for new fd event ret = ppoll(fds, nfds, &tdiff, NULL); +#else +#ifdef HAVE_PSELECT + // set readfds to inital checkfds + fd_set readfds = checkfds; + // wait for new fd event + ret = pselect(maxfd + 1, &readfds, NULL, NULL, &tdiff, NULL); +#endif +#endif - if (ret == 0) { + if (ret == 0) continue; - } +#ifdef HAVE_PPOLL // new data from notify if (fds[0].revents & POLLIN) break; // new data from socket if (fds[1].revents & POLLIN) { +#else +#ifdef HAVE_PSELECT + // new data from notify + if (FD_ISSET(m_notify.notifyFD(), &readfds)) + break; + + // new data from socket + if (FD_ISSET(m_socket->getFD(), &readfds)) { +#endif +#endif + char data[256]; size_t datalen; @@ -139,14 +184,17 @@ void* Network::run() m_running = true; - int ret, nfds = 2; - struct pollfd fds[nfds]; + int ret; struct timespec tdiff; // set select timeout 1 secs tdiff.tv_sec = 1; tdiff.tv_nsec = 0; +#ifdef HAVE_PPOLL + int nfds = 2; + struct pollfd fds[nfds]; + memset(fds, 0, sizeof(fds)); fds[0].fd = m_notify.notifyFD(); @@ -154,16 +202,40 @@ void* Network::run() fds[1].fd = m_tcpServer->getFD(); fds[1].events = POLLIN; +#else +#ifdef HAVE_PSELECT + int maxfd; + fd_set checkfds; + + FD_ZERO(&checkfds); + FD_SET(m_notify.notifyFD(), &checkfds); + FD_SET(m_tcpServer->getFD(), &checkfds); + + (m_notify.notifyFD() > m_tcpServer->getFD()) ? + (maxfd = m_notify.notifyFD()) : (maxfd = m_tcpServer->getFD()); +#endif +#endif for (;;) { + +#ifdef HAVE_PPOLL // wait for new fd event ret = ppoll(fds, nfds, &tdiff, NULL); +#else +#ifdef HAVE_PSELECT + // set readfds to inital checkfds + fd_set readfds = checkfds; + // wait for new fd event + ret = pselect(maxfd + 1, &readfds, NULL, NULL, &tdiff, NULL); +#endif +#endif if (ret == 0) { cleanConnections(); continue; } +#ifdef HAVE_PPOLL // new data from notify if (fds[0].revents & POLLIN) { m_running = false; @@ -172,6 +244,19 @@ void* Network::run() // new data from socket if (fds[1].revents & POLLIN) { +#else +#ifdef HAVE_PSELECT + // new data from notify + if (FD_ISSET(m_notify.notifyFD(), &readfds)) { + m_running = false; + break; + } + + // new data from socket + if (FD_ISSET(m_tcpServer->getFD(), &readfds)) { +#endif +#endif + TCPSocket* socket = m_tcpServer->newSocket(); if (socket == NULL) continue; diff --git a/src/lib/ebus/port.cpp b/src/lib/ebus/port.cpp index 16872806..856ce198 100644 --- a/src/lib/ebus/port.cpp +++ b/src/lib/ebus/port.cpp @@ -17,6 +17,10 @@ * along with ebusd. If not, see http://www.gnu.org/licenses/. */ +#ifdef HAVE_CONFIG_H +#include +#endif + #include "port.h" #include #include @@ -24,7 +28,10 @@ #include #include #include + +#ifdef HAVE_PPOLL #include +#endif bool Device::isOpen() { @@ -64,20 +71,33 @@ ssize_t Device::recvBytes(const long timeout, size_t maxCount) return -1; // TODO RESULT_ERR_DEVICE if (timeout > 0) { - int ret, nfds = 1; - struct pollfd fds[nfds]; + int ret; struct timespec tdiff; // set select timeout tdiff.tv_sec = 0; tdiff.tv_nsec = timeout*1000; +#ifdef HAVE_PPOLL + int nfds = 1; + struct pollfd fds[nfds]; + memset(fds, 0, sizeof(fds)); fds[0].fd = m_fd; fds[0].events = POLLIN; ret = ppoll(fds, nfds, &tdiff, NULL); +#else +#ifdef HAVE_PSELECT + fd_set readfds; + + FD_ZERO(&readfds); + FD_SET(m_fd, &readfds); + + ret = pselect(m_fd + 1, &readfds, NULL, NULL, &tdiff, NULL); +#endif +#endif if (ret == -1) return -1; // TODO RESULT_ERR_DEVICE if (ret == 0) return -2; // TODO RESULT_ERR_TIMEOUT