Icarus: Use epoll (where available) to get nonces ASAP
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
diff --git a/configure.ac b/configure.ac
index 4f7ed9a..2be6eef 100644
--- a/configure.ac
+++ b/configure.ac
@@ -301,6 +301,8 @@ if test "x$bitforce" != xno; then
fi
AM_CONDITIONAL([HAVE_LIBUDEV], [test x$libudev != xno])
+AC_CHECK_HEADERS([sys/epoll.h])
+
PKG_PROG_PKG_CONFIG()
PKG_CHECK_MODULES([LIBCURL], [libcurl >= 7.15.6], [AC_DEFINE([CURL_HAS_SOCKOPT], [1], [Defined if version of curl supports sockopts.])],
diff --git a/driver-icarus.c b/driver-icarus.c
index 4aab784..8ec76eb 100644
--- a/driver-icarus.c
+++ b/driver-icarus.c
@@ -46,10 +46,16 @@
#include <windows.h>
#include <io.h>
#endif
+#ifdef HAVE_SYS_EPOLL_H
+ #include <sys/epoll.h>
+ #define HAVE_EPOLL
+#endif
#include "elist.h"
#include "miner.h"
+// 8 second timeout
+#define ICARUS_READ_FAULT_DECISECONDS (10)
#define ICARUS_READ_FAULT_COUNT (8)
struct device_api icarus_api;
@@ -87,7 +93,7 @@ static int icarus_open(const char *devpath)
ISTRIP | INLCR | IGNCR | ICRNL | IXON);
my_termios.c_oflag &= ~OPOST;
my_termios.c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
- my_termios.c_cc[VTIME] = 10; /* block 1 second */
+ my_termios.c_cc[VTIME] = ICARUS_READ_FAULT_DECISECONDS;
my_termios.c_cc[VMIN] = 0;
tcsetattr(serialfd, TCSANOW, &my_termios);
@@ -112,8 +118,27 @@ static int icarus_gets(unsigned char *buf, size_t bufLen, int fd)
{
ssize_t ret = 0;
int rc = 0;
+ int epollfd = -1;
+
+#ifdef HAVE_EPOLL
+ struct epoll_event ev, evr;
+ epollfd = epoll_create(1);
+ if (epollfd != -1) {
+ ev.events = EPOLLIN;
+ ev.data.fd = fd;
+ if (-1 == epoll_ctl(epollfd, EPOLL_CTL_ADD, fd, &ev)) {
+ close(epollfd);
+ epollfd = -1;
+ }
+ }
+#endif
while (bufLen) {
+#ifdef HAVE_EPOLL
+ if (epollfd != -1 && epoll_wait(epollfd, &evr, 1, ICARUS_READ_FAULT_DECISECONDS * 100) != 1)
+ ret = 0;
+ else
+#endif
ret = read(fd, buf, 1);
if (ret == 1) {
bufLen--;
@@ -123,12 +148,17 @@ static int icarus_gets(unsigned char *buf, size_t bufLen, int fd)
rc++;
if (rc == ICARUS_READ_FAULT_COUNT) {
+ if (epollfd != -1)
+ close(epollfd);
applog(LOG_DEBUG,
- "Icarus Read: No data in %d seconds", rc);
+ "Icarus Read: No data in %d seconds", rc * ICARUS_READ_FAULT_DECISECONDS / 10);
return 1;
}
}
+ if (epollfd != -1)
+ close(epollfd);
+
return 0;
}