@@ -39,10 +39,47 @@ nsapi_error_t TCPSocket::connect(const SocketAddress &address)
39
39
_lock.lock ();
40
40
nsapi_error_t ret;
41
41
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 ;
45
57
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;
46
83
}
47
84
48
85
_lock.unlock ();
@@ -81,9 +118,8 @@ nsapi_size_or_error_t TCPSocket::send(const void *data, nsapi_size_t size)
81
118
}
82
119
83
120
_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)) {
87
123
break ;
88
124
} else {
89
125
int32_t count;
@@ -125,9 +161,8 @@ nsapi_size_or_error_t TCPSocket::recv(void *data, nsapi_size_t size)
125
161
}
126
162
127
163
_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)) {
131
166
break ;
132
167
} else {
133
168
int32_t count;
0 commit comments