Skip to content

Commit 41b292f

Browse files
committed
Prevent uxr_read_*_data_platform() from blocking too long
This commit sets the timeout in uxr_read_*_data_platform() to 0 after the first occurrence of an EINTR interrupt. This ensures that the function will never block longer than the specified timeout. But it may return early if an interrupt occurs. Signed-off-by: J. S. Seldenthuis <jseldenthuis@lely.com>
1 parent 3d1dcc7 commit 41b292f

File tree

4 files changed

+24
-16
lines changed

4 files changed

+24
-16
lines changed

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ size_t uxr_read_tcp_data_platform(
126126
{
127127
errno = errsv;
128128
poll_rv = poll(&platform->poll_fd, 1, timeout);
129+
timeout = 0;
129130
} while (-1 == poll_rv && EINTR == errno);
130131
if (0 < poll_rv)
131132
{

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

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -123,19 +123,22 @@ 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));
133-
134126
ssize_t bytes_received;
135127
do
136128
{
137129
errno = errsv;
130+
131+
timeout = (timeout <= 0) ? 1 : timeout;
132+
133+
struct timeval tv;
134+
tv.tv_sec = timeout / 1000;
135+
tv.tv_usec = (timeout % 1000) * 1000;
136+
137+
setsockopt(platform->fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
138+
138139
bytes_received = recv(platform->fd, (void*)buf, len, 0);
140+
141+
timeout = 0;
139142
} while (-1 == bytes_received && EINTR == errno);
140143
if (-1 != bytes_received)
141144
{

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ size_t uxr_read_udp_data_platform(
113113
{
114114
errno = errsv;
115115
poll_rv = poll(&platform->poll_fd, 1, timeout);
116+
timeout = 0;
116117
} while (-1 == poll_rv && EINTR == errno);
117118
if (0 < poll_rv)
118119
{

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

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -110,19 +110,22 @@ 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));
120-
121113
ssize_t bytes_received;
122114
do
123115
{
124116
errno = errsv;
117+
118+
timeout = (timeout <= 0) ? 1 : timeout;
119+
120+
struct timeval tv;
121+
tv.tv_sec = timeout / 1000;
122+
tv.tv_usec = (timeout % 1000) * 1000;
123+
124+
setsockopt(platform->fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
125+
125126
bytes_received = recv(platform->fd, (void*)buf, len, 0);
127+
128+
timeout = 0;
126129
} while (-1 == bytes_received && EINTR == errno);
127130
if (-1 != bytes_received)
128131
{

0 commit comments

Comments
 (0)