summaryrefslogtreecommitdiff
path: root/tools/select.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/select.c')
-rw-r--r--tools/select.c52
1 files changed, 52 insertions, 0 deletions
diff --git a/tools/select.c b/tools/select.c
new file mode 100644
index 0000000..77229c8
--- /dev/null
+++ b/tools/select.c
@@ -0,0 +1,52 @@
+#include "tools/select.h"
+
+#include <vdr/tools.h>
+#include <sys/time.h>
+#include <sys/types.h>
+#include <time.h>
+#include <unistd.h>
+#include <errno.h>
+
+cTBSelect::cTBSelect(void) {
+ Clear();
+}
+
+cTBSelect::~cTBSelect() {
+}
+
+int cTBSelect::Select(uint TimeoutMs) {
+ struct timeval tv;
+ time_t st, et;
+ ssize_t res;
+ int ms;
+
+ tv.tv_usec = (TimeoutMs % 1000) * 1000;
+ tv.tv_sec = TimeoutMs / 1000;
+
+ if (TimeoutMs == 0)
+ return ::select(m_MaxFiled + 1, &m_Rfds, &m_Wfds, NULL, &tv);
+
+ st = time_ms();
+ ms = TimeoutMs;
+ while (ms > 0 && (res = ::select(m_MaxFiled + 1, &m_Rfds, &m_Wfds, NULL,
+ &tv)) == -1 && errno == EINTR) {
+ et = time_ms();
+ ms -= et - st;
+ tv.tv_usec = (ms % 1000) * 1000;
+ tv.tv_sec = ms / 1000;
+ st = et;
+ }
+ if (ms <= 0) {
+ errno = ETIMEDOUT;
+ return -1;
+ }
+ return res;
+}
+
+int cTBSelect::Select(void) {
+ ssize_t res;
+ while ((res = ::select(m_MaxFiled + 1, &m_Rfds, &m_Wfds, NULL, NULL)) == -1
+ && errno == EINTR)
+ ;
+ return res;
+}