Skip to content

Commit

Permalink
feat(el): Poll if 'send' blocks with EWOULDBLOCK
Browse files Browse the repository at this point in the history
Adapter for the EventLoop from commit
524bf00 by Emmanuel Pacaud
<[email protected]>
  • Loading branch information
jpfr committed Dec 27, 2021
1 parent 6b537bb commit 1497457
Show file tree
Hide file tree
Showing 7 changed files with 36 additions and 21 deletions.
1 change: 1 addition & 0 deletions arch/eCos/ua_architecture.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
#define UA_ERRNO errno
#define UA_INTERRUPTED EINTR
#define UA_AGAIN EAGAIN /* the same as wouldblock on nearly every system */
#define UA_INPROGRESS EINPROGRESS
#define UA_WOULDBLOCK EWOULDBLOCK

#define UA_getnameinfo(sa, salen, host, hostlen, serv, servlen, flags) \
Expand Down
41 changes: 28 additions & 13 deletions arch/eventloop_posix_tcp.c
Original file line number Diff line number Diff line change
Expand Up @@ -479,6 +479,10 @@ TCP_sendWithConnection(UA_ConnectionManager *cm, uintptr_t connectionId,
/* Prevent OS signals when sending to a closed socket */
int flags = MSG_NOSIGNAL;

struct pollfd tmp_poll_fd;
tmp_poll_fd.fd = (UA_FD)connectionId;
tmp_poll_fd.events = UA_POLLOUT;

/* Send the full buffer. This may require several calls to send */
size_t nWritten = 0;
do {
Expand All @@ -491,18 +495,27 @@ TCP_sendWithConnection(UA_ConnectionManager *cm, uintptr_t connectionId,
n = UA_send((UA_FD)connectionId,
(const char*)buf->data + nWritten,
bytes_to_send, flags);
if(n < 0 &&
UA_ERRNO != UA_INTERRUPTED &&
UA_ERRNO != UA_WOULDBLOCK &&
UA_ERRNO != UA_AGAIN) {
UA_LOG_SOCKET_ERRNO_GAI_WRAP(
UA_LOG_ERROR(UA_EventLoop_getLogger(cm->eventSource.eventLoop),
UA_LOGCATEGORY_NETWORK,
"TCP %u\t| Send failed with error %s",
(unsigned)connectionId, errno_str));
TCP_shutdownConnection(cm, connectionId);
UA_ByteString_clear(buf);
return UA_STATUSCODE_BADCONNECTIONCLOSED;
if(n < 0) {
/* An error we cannot recover from? */
if(UA_ERRNO != UA_INTERRUPTED &&
UA_ERRNO != UA_WOULDBLOCK &&
UA_ERRNO != UA_AGAIN) {
UA_LOG_SOCKET_ERRNO_GAI_WRAP(
UA_LOG_ERROR(UA_EventLoop_getLogger(cm->eventSource.eventLoop),
UA_LOGCATEGORY_NETWORK,
"TCP %u\t| Send failed with error %s",
(unsigned)connectionId, errno_str));
TCP_shutdownConnection(cm, connectionId);
UA_ByteString_clear(buf);
return UA_STATUSCODE_BADCONNECTIONCLOSED;
}

/* Poll for the socket resources to become available and retry
* (blocking) */
int poll_ret;
do {
poll_ret = UA_poll(&tmp_poll_fd, 1, 100);
} while(poll_ret == 0 || (poll_ret < 0 && UA_ERRNO == UA_INTERRUPTED));
}
} while(n < 0);
nWritten += (size_t)n;
Expand Down Expand Up @@ -604,7 +617,9 @@ TCP_openConnection(UA_ConnectionManager *cm,
/* Non-blocking connect */
error = UA_connect(newSock, info->ai_addr, info->ai_addrlen);
freeaddrinfo(info);
if(error != 0 && UA_ERRNO != UA_WOULDBLOCK) {
if(error != 0 &&
UA_ERRNO != UA_INPROGRESS &&
UA_ERRNO != UA_WOULDBLOCK) {
UA_LOG_SOCKET_ERRNO_WRAP(
UA_LOG_ERROR(UA_EventLoop_getLogger(cm->eventSource.eventLoop),
UA_LOGCATEGORY_NETWORK,
Expand Down
2 changes: 1 addition & 1 deletion arch/network_tcp.c
Original file line number Diff line number Diff line change
Expand Up @@ -795,7 +795,7 @@ UA_ClientConnectionTCP_poll(UA_Connection *connection, UA_UInt32 timeout,
tcpConnection->server->ai_addrlen);
if((error == -1 && UA_ERRNO == EISCONN) || (error == 0))
resultsize = 1;
if(error == -1 && UA_ERRNO != EALREADY && UA_ERRNO != EINPROGRESS)
if(error == -1 && UA_ERRNO != UA_ALREADY && UA_ERRNO != UA_INPROGRESS)
break;
} while(resultsize == 0);
#else
Expand Down
1 change: 1 addition & 0 deletions arch/posix/ua_architecture.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ void UA_sleep_ms(unsigned long ms);
#define UA_ERRNO errno
#define UA_INTERRUPTED EINTR
#define UA_AGAIN EAGAIN /* the same as wouldblock on nearly every system */
#define UA_INPROGRESS EINPROGRESS
#define UA_WOULDBLOCK EWOULDBLOCK

#define UA_POLLIN POLLIN
Expand Down
1 change: 1 addition & 0 deletions arch/vxworks/ua_architecture.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
#define UA_ERRNO errno
#define UA_INTERRUPTED EINTR
#define UA_AGAIN EAGAIN /* the same as wouldblock on nearly every system */
#define UA_INPROGRESS EINPROGRESS
#define UA_WOULDBLOCK EWOULDBLOCK

#define UA_ENABLE_LOG_COLORS
Expand Down
10 changes: 3 additions & 7 deletions arch/wec7/ua_architecture.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,16 +62,12 @@ void UA_sleep_ms(unsigned long ms);
// Windows does not support ansi colors
// #define UA_ENABLE_LOG_COLORS

#if defined(__MINGW32__) //mingw defines SOCKET as long long unsigned int, giving errors in logging and when comparing with UA_Int32
# define UA_SOCKET int
# define UA_INVALID_SOCKET -1
#else
# define UA_SOCKET SOCKET
# define UA_INVALID_SOCKET INVALID_SOCKET
#endif
#define UA_SOCKET SOCKET
#define UA_INVALID_SOCKET INVALID_SOCKET
#define UA_ERRNO WSAGetLastError()
#define UA_INTERRUPTED WSAEINTR
#define UA_AGAIN EAGAIN /* the same as wouldblock on nearly every system */
#define UA_INPROGRESS EINPROGRESS
#define UA_WOULDBLOCK WSAEWOULDBLOCK

#define UA_fd_set(fd, fds) FD_SET((UA_SOCKET)fd, fds)
Expand Down
1 change: 1 addition & 0 deletions arch/win32/ua_architecture.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ void UA_sleep_ms(unsigned long ms);
#define UA_ERRNO WSAGetLastError()
#define UA_INTERRUPTED WSAEINTR
#define UA_AGAIN EAGAIN /* the same as wouldblock on nearly every system */
#define UA_INPROGRESS WSAEINPROGRESS
#define UA_WOULDBLOCK WSAEWOULDBLOCK
#define UA_POLLIN POLLRDNORM
#define UA_POLLOUT POLLWRNORM
Expand Down

0 comments on commit 1497457

Please sign in to comment.