Instrument Neutral Distributed Interface INDI 2.2.5
select.h
Go to the documentation of this file.
1/*
2 Copyright (C) 2022 by Pawel Soja <[email protected]>
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Lesser General Public
6 License as published by the Free Software Foundation; either
7 version 2.1 of the License, or (at your option) any later version.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Lesser General Public License for more details.
13
14 You should have received a copy of the GNU Lesser General Public
15 License along with this library; if not, write to the Free Software
16 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17*/
18// internal use only
19#pragma once
20
21#include <stdio.h>
22#include <algorithm>
23
24#ifdef _WIN32
25#ifndef NOMINMAX
26#define NOMINMAX
27#endif
28#include <ws2tcpip.h>
29#include <winsock2.h>
30#include <windows.h>
31typedef SOCKET SocketFileDescriptor;
32static const SocketFileDescriptor SocketInvalid = INVALID_SOCKET;
33#else
34#define HAS_EVENT_FD
35#include <unistd.h>
36#include <netdb.h>
37#include <sys/socket.h> // select
39static const SocketFileDescriptor SocketInvalid = -1;
40#endif
41
42#include "indimacros.h"
43
44#ifdef HAS_EVENT_FD
46{
47 public:
49 {
50 if (socketpair(PF_UNIX, SOCK_STREAM, 0, pipefd) < 0)
51 {
52 perror("socketpair");
53 }
54 }
55
57 {
58 close(pipefd[0]);
59 close(pipefd[1]);
60 }
61
62 public:
63 void wakeUp()
64 {
65 size_t c = 1;
66 // wakeup 'select' function
67 ssize_t ret = write(pipefd[1], &c, sizeof(c));
68
69 if (ret != sizeof(c))
70 {
71 perror("the socket cannot be woken up");
72 }
73 total += ret;
74 }
75
76 int fd() const
77 {
78 return pipefd[0];
79 }
80
81 void clear()
82 {
83 size_t c = 0;
84 while (total > 0)
85 {
86 total -= read(pipefd[0], &c, sizeof(c));
87 }
88 }
89
90 private:
91 int pipefd[2] = {-1, -1};
92 int total = 0;
93};
94#endif
95
96// wrapper for unix select function
97class Select
98{
99 public:
101 {
102 clear();
103 }
104
105 public:
106 void wakeUp()
107 {
108#ifdef HAS_EVENT_FD
109 eventFd.wakeUp();
110#endif
111 }
112
113 void clear()
114 {
115 FD_ZERO(&readEvent);
116 FD_ZERO(&writeEvent);
117 FD_ZERO(&exceptionEvent);
118 fdMax = 0;
119#ifdef HAS_EVENT_FD
120 eventFd.clear();
121#endif
122 }
123
124 public:
125 void setTimeout(int timeout)
126 {
127 ts.tv_sec = timeout / 1000;
128 ts.tv_usec = (timeout % 1000) * 1000;
129 }
130
131 void select()
132 {
133#ifdef HAS_EVENT_FD
135#endif
137#ifdef HAS_EVENT_FD
138 if (isReadEvent(eventFd.fd()))
139 {
140 eventFd.clear();
141 }
142#endif
143 }
144
145 void select(int timeout)
146 {
147 setTimeout(timeout);
148 select();
149 }
150
151 public:
153 {
154 FD_SET(fd, &readEvent);
155 fdMax = std::max(fdMax, fd);
156 }
157
159 {
160 FD_SET(fd, &writeEvent);
161 fdMax = std::max(fdMax, fd);
162 }
163
165 {
166 FD_SET(fd, &exceptionEvent);
167 fdMax = std::max(fdMax, fd);
168 }
169
171 {
172 FD_SET(fd, &readEvent);
173 FD_SET(fd, &writeEvent);
174 fdMax = std::max(fdMax, fd);
175 }
176
178 {
179 FD_SET(fd, &readEvent);
180 FD_SET(fd, &writeEvent);
181 FD_SET(fd, &exceptionEvent);
182 fdMax = std::max(fdMax, fd);
183 }
184
185 public:
186#ifdef HAS_EVENT_FD
187 bool isWakedUp() const
188 {
189 return FD_ISSET(eventFd.fd(), &readEvent);
190 }
191#else
192 bool isWakedUp() const
193 {
194 return false;
195 }
196#endif
197 bool isTimeout() const
198 {
199 return readyDesc == 0;
200 }
201 bool isError() const
202 {
203 return readyDesc < 0;
204 }
206 {
207 return FD_ISSET(fd, &readEvent);
208 }
210 {
211 return FD_ISSET(fd, &writeEvent);
212 }
214 {
215 return FD_ISSET(fd, &exceptionEvent);
216 }
217
218 protected:
219 fd_set readEvent;
223 int readyDesc {0};
224
225 struct timeval ts
226 {
227 1, 0
228 };
229
230#ifdef HAS_EVENT_FD
232#endif
233};
~EventFd()
Definition select.h:56
void wakeUp()
Definition select.h:63
void clear()
Definition select.h:81
int fd() const
Definition select.h:76
EventFd()
Definition select.h:48
bool isWakedUp() const
Definition select.h:187
bool isError() const
Definition select.h:201
void select(int timeout)
Definition select.h:145
void setReadEvent(SocketFileDescriptor fd)
Definition select.h:152
fd_set exceptionEvent
Definition select.h:221
int readyDesc
Definition select.h:223
void setReadWriteExceptionEvent(SocketFileDescriptor fd)
Definition select.h:177
void setWriteEvent(SocketFileDescriptor fd)
Definition select.h:158
EventFd eventFd
Definition select.h:231
void select()
Definition select.h:131
bool isWriteEvent(SocketFileDescriptor fd) const
Definition select.h:209
void setTimeout(int timeout)
Definition select.h:125
bool isTimeout() const
Definition select.h:197
void wakeUp()
Definition select.h:106
void setReadWriteEvent(SocketFileDescriptor fd)
Definition select.h:170
bool isExceptionEvent(SocketFileDescriptor fd) const
Definition select.h:213
void clear()
Definition select.h:113
void setExceptionEvent(SocketFileDescriptor fd)
Definition select.h:164
fd_set readEvent
Definition select.h:219
Select()
Definition select.h:100
fd_set writeEvent
Definition select.h:220
SocketFileDescriptor fdMax
Definition select.h:222
bool isReadEvent(SocketFileDescriptor fd) const
Definition select.h:205
#define INVALID_SOCKET
Definition httplib.h:273
int fd
int SocketFileDescriptor
Definition select.h:38