Skip to content

Commit 18b285a

Browse files
committed
Prevent uxr_read_*_data_platform() from blocking too long
This commit recomputes the timeout in uxr_read_*_data_platform() after each occurrence of an EINTR interrupt. This ensures that the function will never block longer than the specified timeout. Signed-off-by: J. S. Seldenthuis <jseldenthuis@lely.com>
1 parent 3d1dcc7 commit 18b285a

4 files changed

Lines changed: 36 additions & 16 deletions

File tree

src/c/profile/transport/ip/tcp/tcp_transport_posix.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,11 +121,15 @@ size_t uxr_read_tcp_data_platform(
121121
{
122122
size_t rv = 0;
123123
int errsv = errno;
124+
int64_t start_timestamp = uxr_millis();
125+
int remaining_time = timeout;
124126
int poll_rv;
125127
do
126128
{
127129
errno = errsv;
128-
poll_rv = poll(&platform->poll_fd, 1, timeout);
130+
remaining_time = (remaining_time <= 0) ? 0 : remaining_time;
131+
poll_rv = poll(&platform->poll_fd, 1, remaining_time);
132+
remaining_time = timeout - (int)(uxr_millis() - start_timestamp);
129133
} while (-1 == poll_rv && EINTR == errno);
130134
if (0 < poll_rv)
131135
{

src/c/profile/transport/ip/tcp/tcp_transport_posix_nopoll.c

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -123,19 +123,25 @@ size_t uxr_read_tcp_data_platform(
123123
size_t rv = 0;
124124
int errsv = errno;
125125

126-
timeout = (timeout <= 0) ? 1 : timeout;
127-
128-
struct timeval tv;
129-
tv.tv_sec = timeout / 1000;
130-
tv.tv_usec = (timeout % 1000) * 1000;
131-
132-
setsockopt(platform->fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
126+
int64_t start_timestamp = uxr_millis();
127+
int remaining_time = timeout;
133128

134129
ssize_t bytes_received;
135130
do
136131
{
137132
errno = errsv;
133+
134+
remaining_time = (remaining_time <= 0) ? 1 : remaining_time;
135+
136+
struct timeval tv;
137+
tv.tv_sec = remaining_time / 1000;
138+
tv.tv_usec = (remaining_time % 1000) * 1000;
139+
140+
setsockopt(platform->fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
141+
138142
bytes_received = recv(platform->fd, (void*)buf, len, 0);
143+
144+
remaining_time = timeout - (int)(uxr_millis() - start_timestamp);
139145
} while (-1 == bytes_received && EINTR == errno);
140146
if (-1 != bytes_received)
141147
{

src/c/profile/transport/ip/udp/udp_transport_posix.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,11 +108,15 @@ size_t uxr_read_udp_data_platform(
108108
{
109109
size_t rv = 0;
110110
int errsv = errno;
111+
int64_t start_timestamp = uxr_millis();
112+
int remaining_time = timeout;
111113
int poll_rv;
112114
do
113115
{
114116
errno = errsv;
115-
poll_rv = poll(&platform->poll_fd, 1, timeout);
117+
remaining_time = (remaining_time <= 0) ? 0 : remaining_time;
118+
poll_rv = poll(&platform->poll_fd, 1, remaining_time);
119+
remaining_time = timeout - (int)(uxr_millis() - start_timestamp);
116120
} while (-1 == poll_rv && EINTR == errno);
117121
if (0 < poll_rv)
118122
{

src/c/profile/transport/ip/udp/udp_transport_posix_nopoll.c

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -110,19 +110,25 @@ size_t uxr_read_udp_data_platform(
110110
size_t rv = 0;
111111
int errsv = errno;
112112

113-
timeout = (timeout <= 0) ? 1 : timeout;
114-
115-
struct timeval tv;
116-
tv.tv_sec = timeout / 1000;
117-
tv.tv_usec = (timeout % 1000) * 1000;
118-
119-
setsockopt(platform->fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
113+
int64_t start_timestamp = uxr_millis();
114+
int remaining_time = timeout;
120115

121116
ssize_t bytes_received;
122117
do
123118
{
124119
errno = errsv;
120+
121+
remaining_time = (remaining_time <= 0) ? 1 : remaining_time;
122+
123+
struct timeval tv;
124+
tv.tv_sec = remaining_time / 1000;
125+
tv.tv_usec = (remaining_time % 1000) * 1000;
126+
127+
setsockopt(platform->fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
128+
125129
bytes_received = recv(platform->fd, (void*)buf, len, 0);
130+
131+
remaining_time = timeout - (int)(uxr_millis() - start_timestamp);
126132
} while (-1 == bytes_received && EINTR == errno);
127133
if (-1 != bytes_received)
128134
{

0 commit comments

Comments
 (0)