Skip to content

Commit bba527f

Browse files
authored
Merge pull request #3457 from hasnainvirk/nsapi_connect
[ONME-2844] Supporting non-blocking connect()
2 parents d652d39 + 35e4896 commit bba527f

File tree

2 files changed

+47
-9
lines changed

2 files changed

+47
-9
lines changed

features/netsocket/TCPSocket.cpp

Lines changed: 44 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,47 @@ nsapi_error_t TCPSocket::connect(const SocketAddress &address)
3939
_lock.lock();
4040
nsapi_error_t ret;
4141

42-
if (!_socket) {
43-
ret = NSAPI_ERROR_NO_SOCKET;
44-
} else {
42+
// If this assert is hit then there are two threads
43+
// performing a send at the same time which is undefined
44+
// behavior
45+
MBED_ASSERT(!_write_in_progress);
46+
_write_in_progress = true;
47+
48+
bool blocking_connect_in_progress = false;
49+
50+
while (true) {
51+
if (!_socket) {
52+
ret = NSAPI_ERROR_NO_SOCKET;
53+
break;
54+
}
55+
56+
_pending = 0;
4557
ret = _stack->socket_connect(_socket, address);
58+
if ((_timeout == 0) || !(ret == NSAPI_ERROR_IN_PROGRESS || ret == NSAPI_ERROR_ALREADY)) {
59+
break;
60+
} else {
61+
blocking_connect_in_progress = true;
62+
63+
int32_t count;
64+
65+
// Release lock before blocking so other threads
66+
// accessing this object aren't blocked
67+
_lock.unlock();
68+
count = _write_sem.wait(_timeout);
69+
_lock.lock();
70+
71+
if (count < 1) {
72+
// Semaphore wait timed out so break out and return
73+
break;
74+
}
75+
}
76+
}
77+
78+
_write_in_progress = false;
79+
80+
/* Non-blocking connect gives "EISCONN" once done - convert to OK for blocking mode if we became connected during this call */
81+
if (ret == NSAPI_ERROR_IS_CONNECTED && blocking_connect_in_progress) {
82+
ret = NSAPI_ERROR_OK;
4683
}
4784

4885
_lock.unlock();
@@ -81,9 +118,8 @@ nsapi_size_or_error_t TCPSocket::send(const void *data, nsapi_size_t size)
81118
}
82119

83120
_pending = 0;
84-
nsapi_size_or_error_t sent = _stack->socket_send(_socket, data, size);
85-
if ((0 == _timeout) || (NSAPI_ERROR_WOULD_BLOCK != sent)) {
86-
ret = sent;
121+
ret = _stack->socket_send(_socket, data, size);
122+
if ((_timeout == 0) || (ret != NSAPI_ERROR_WOULD_BLOCK)) {
87123
break;
88124
} else {
89125
int32_t count;
@@ -125,9 +161,8 @@ nsapi_size_or_error_t TCPSocket::recv(void *data, nsapi_size_t size)
125161
}
126162

127163
_pending = 0;
128-
nsapi_size_or_error_t recv = _stack->socket_recv(_socket, data, size);
129-
if ((0 == _timeout) || (NSAPI_ERROR_WOULD_BLOCK != recv)) {
130-
ret = recv;
164+
ret = _stack->socket_recv(_socket, data, size);
165+
if ((_timeout == 0) || (ret != NSAPI_ERROR_WOULD_BLOCK)) {
131166
break;
132167
} else {
133168
int32_t count;

features/netsocket/nsapi_types.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,9 @@ enum nsapi_error {
4848
NSAPI_ERROR_DHCP_FAILURE = -3010, /*!< DHCP failed to complete successfully */
4949
NSAPI_ERROR_AUTH_FAILURE = -3011, /*!< connection to access point failed */
5050
NSAPI_ERROR_DEVICE_ERROR = -3012, /*!< failure interfacing with the network processor */
51+
NSAPI_ERROR_IN_PROGRESS = -3013, /*!< operation (eg connect) in progress */
52+
NSAPI_ERROR_ALREADY = -3014, /*!< operation (eg connect) already in progress */
53+
NSAPI_ERROR_IS_CONNECTED = -3015, /*!< socket is already connected */
5154
};
5255

5356
/** Type used to represent error codes

0 commit comments

Comments
 (0)