Skip to content

Commit 26a7e44

Browse files
author
Seppo Takalo
committed
Move accept() to abstract socket class and implement in TCPSocket
Deprecate TCPServer in favor of just TCPSocket::accept()
1 parent 570d255 commit 26a7e44

File tree

9 files changed

+243
-173
lines changed

9 files changed

+243
-173
lines changed

features/netsocket/InternetSocket.cpp

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,9 @@
2020
using namespace mbed;
2121

2222
InternetSocket::InternetSocket()
23-
: _stack(0)
24-
, _socket(0)
25-
, _timeout(osWaitForever)
23+
: _stack(0), _socket(0), _timeout(osWaitForever),
24+
_readers(0), _writers(0), _factory_allocated(false),
25+
_pending(0)
2626
{
2727
}
2828

@@ -68,7 +68,19 @@ nsapi_error_t InternetSocket::close()
6868
// on this socket
6969
event();
7070

71+
// Wait until all readers and writers are gone
72+
while (_readers || _writers) {
73+
_lock.unlock();
74+
_event_flag.wait_any(FINISHED_FLAG, osWaitForever);
75+
_lock.lock();
76+
}
77+
7178
_lock.unlock();
79+
80+
// When allocated by accept() call, will self desctruct on close();
81+
if (_factory_allocated) {
82+
delete this;
83+
}
7284
return ret;
7385
}
7486

@@ -172,6 +184,15 @@ nsapi_error_t InternetSocket::getsockopt(int level, int optname, void *optval, u
172184
return ret;
173185

174186
}
187+
void InternetSocket::event()
188+
{
189+
_event_flag.set(READ_FLAG|WRITE_FLAG);
190+
191+
_pending += 1;
192+
if (_callback && _pending == 1) {
193+
_callback();
194+
}
195+
}
175196

176197
void InternetSocket::sigio(Callback<void()> callback)
177198
{

features/netsocket/InternetSocket.h

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
#include "netsocket/Socket.h"
2424
#include "netsocket/NetworkStack.h"
2525
#include "rtos/Mutex.h"
26+
#include "rtos/EventFlags.h"
2627
#include "Callback.h"
2728
#include "mbed_toolchain.h"
2829

@@ -217,16 +218,26 @@ class InternetSocket : public Socket {
217218
protected:
218219
InternetSocket();
219220
virtual nsapi_protocol_t get_proto() = 0;
220-
virtual void event() = 0;
221+
virtual void event();
221222
int modify_multicast_group(const SocketAddress &address, nsapi_socket_option_t socketopt);
222223

223224
NetworkStack *_stack;
224225
nsapi_socket_t _socket;
225226
uint32_t _timeout;
226227
mbed::Callback<void()> _event;
227228
mbed::Callback<void()> _callback;
229+
rtos::EventFlags _event_flag;
228230
rtos::Mutex _lock;
229231
SocketAddress _remote_peer;
232+
uint8_t _readers;
233+
uint8_t _writers;
234+
volatile unsigned _pending;
235+
bool _factory_allocated;
236+
237+
// Event flags
238+
static const int READ_FLAG = 0x1u;
239+
static const int WRITE_FLAG = 0x2u;
240+
static const int FINISHED_FLAG = 0x3u;
230241
};
231242

232243
#endif // INTERNETSOCKET_H

features/netsocket/Socket.h

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -110,11 +110,10 @@ class Socket {
110110
/** Receive a data from a socket
111111
*
112112
* Receives a data and stores the source address in address if address
113-
* is not NULL. Returns the number of bytes written into the buffer. If the
114-
* datagram is larger than the buffer, the excess data is silently discarded.
113+
* is not NULL. Returns the number of bytes written into the buffer.
115114
*
116115
* By default, recvfrom blocks until a datagram is received. If socket is set to
117-
* non-blocking or times out with no datagram, NSAPI_ERROR_WOULD_BLOCK
116+
* non-blocking or times out with no data, NSAPI_ERROR_WOULD_BLOCK
118117
* is returned.
119118
*
120119
* @param address Destination for the source address or NULL
@@ -213,6 +212,32 @@ class Socket {
213212
* @return 0 on success, negative error code on failure
214213
*/
215214
virtual nsapi_error_t getsockopt(int level, int optname, void *optval, unsigned *optlen) = 0;
215+
216+
/** Accepts a connection on a socket.
217+
*
218+
* The server socket must be bound and set to listen for connections.
219+
* On a new connection, returns connected network socket which user is expected to call close()
220+
* and that deallocates the resources. Referencing a returned pointer after a close()
221+
* call is not allowed and leads to undefined behaviour.
222+
*
223+
* By default, accept blocks until incomming connection occurs. If socket is set to
224+
* non-blocking or times out, error is set to NSAPI_ERROR_WOULD_BLOCK.
225+
*
226+
* @param error pointer to storage of the error value or NULL
227+
* @return pointer to a socket
228+
*/
229+
virtual Socket *accept(nsapi_error_t *error = NULL) = 0;
230+
231+
/** Listen for incoming connections.
232+
*
233+
* Marks the socket as a passive socket that can be used to accept
234+
* incoming connections.
235+
*
236+
* @param backlog Number of pending connections that can be queued
237+
* simultaneously, defaults to 1
238+
* @return 0 on success, negative error code on failure
239+
*/
240+
virtual nsapi_error_t listen(int backlog = 1) = 0;
216241
};
217242

218243

features/netsocket/TCPServer.cpp

Lines changed: 6 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
#include "mbed.h"
1919

2020
TCPServer::TCPServer()
21-
: _pending(0), _accept_sem(0)
2221
{
2322
}
2423

@@ -27,29 +26,9 @@ TCPServer::~TCPServer()
2726
close();
2827
}
2928

30-
nsapi_protocol_t TCPServer::get_proto()
31-
{
32-
return NSAPI_TCP;
33-
}
34-
35-
nsapi_error_t TCPServer::listen(int backlog)
36-
{
37-
_lock.lock();
38-
nsapi_error_t ret;
39-
40-
if (!_socket) {
41-
ret = NSAPI_ERROR_NO_SOCKET;
42-
} else {
43-
ret = _stack->socket_listen(_socket, backlog);
44-
}
45-
46-
_lock.unlock();
47-
return ret;
48-
}
49-
5029
nsapi_error_t TCPServer::accept(TCPSocket *connection, SocketAddress *address)
5130
{
52-
_lock.lock();
31+
//TODO!!!!
5332
nsapi_error_t ret;
5433

5534
while (true) {
@@ -76,19 +55,19 @@ nsapi_error_t TCPServer::accept(TCPSocket *connection, SocketAddress *address)
7655

7756
connection->_lock.unlock();
7857
break;
79-
} else if (NSAPI_ERROR_WOULD_BLOCK != ret) {
58+
} else if ((_timeout == 0) || (ret != NSAPI_ERROR_WOULD_BLOCK)) {
8059
break;
8160
} else {
82-
int32_t count;
61+
uint32_t flag;
8362

8463
// Release lock before blocking so other threads
8564
// accessing this object aren't blocked
8665
_lock.unlock();
87-
count = _accept_sem.wait(_timeout);
66+
flag = _event_flag.wait_any(READ_FLAG, _timeout);
8867
_lock.lock();
8968

90-
if (count < 1) {
91-
// Semaphore wait timed out so break out and return
69+
if (flag & osFlagsError) {
70+
// Timeout break
9271
ret = NSAPI_ERROR_WOULD_BLOCK;
9372
break;
9473
}
@@ -98,41 +77,3 @@ nsapi_error_t TCPServer::accept(TCPSocket *connection, SocketAddress *address)
9877
_lock.unlock();
9978
return ret;
10079
}
101-
102-
void TCPServer::event()
103-
{
104-
int32_t acount = _accept_sem.wait(0);
105-
if (acount <= 1) {
106-
_accept_sem.release();
107-
}
108-
109-
_pending += 1;
110-
if (_callback && _pending == 1) {
111-
_callback();
112-
}
113-
}
114-
115-
nsapi_error_t TCPServer::connect(const SocketAddress)
116-
{
117-
return NSAPI_ERROR_UNSUPPORTED;
118-
}
119-
120-
nsapi_size_or_error_t TCPServer::send(const void *, nsapi_size_t)
121-
{
122-
return NSAPI_ERROR_UNSUPPORTED;
123-
}
124-
125-
nsapi_size_or_error_t TCPServer::recv(void *, nsapi_size_t)
126-
{
127-
return NSAPI_ERROR_UNSUPPORTED;
128-
}
129-
130-
nsapi_size_or_error_t TCPServer::sendto(const SocketAddress&, const void *, nsapi_size_t)
131-
{
132-
return NSAPI_ERROR_UNSUPPORTED;
133-
}
134-
135-
nsapi_size_or_error_t TCPServer::recvfrom(SocketAddress*, void *, nsapi_size_t)
136-
{
137-
return NSAPI_ERROR_UNSUPPORTED;
138-
}

features/netsocket/TCPServer.h

Lines changed: 7 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,14 @@
2828
/** TCP socket server
2929
* @addtogroup netsocket
3030
*/
31-
class TCPServer : public InternetSocket {
31+
class TCPServer : public TCPSocket {
3232
public:
3333
/** Create an uninitialized socket
3434
*
3535
* Must call open to initialize the socket on a network stack.
3636
*/
37+
MBED_DEPRECATED_SINCE("mbed-os-5.10",
38+
"TCPServer is deprecated, use TCPSocket")
3739
TCPServer();
3840

3941
/** Create a socket on a network interface
@@ -44,8 +46,9 @@ class TCPServer : public InternetSocket {
4446
* @param stack Network stack as target for socket
4547
*/
4648
template <typename S>
49+
MBED_DEPRECATED_SINCE("mbed-os-5.10",
50+
"TCPServer is deprecated, use TCPSocket")
4751
TCPServer(S *stack)
48-
: _pending(0), _accept_sem(0)
4952
{
5053
open(stack);
5154
}
@@ -56,17 +59,6 @@ class TCPServer : public InternetSocket {
5659
*/
5760
virtual ~TCPServer();
5861

59-
/** Listen for connections on a TCP socket
60-
*
61-
* Marks the socket as a passive socket that can be used to accept
62-
* incoming connections.
63-
*
64-
* @param backlog Number of pending connections that can be queued
65-
* simultaneously, defaults to 1
66-
* @return 0 on success, negative error code on failure
67-
*/
68-
nsapi_error_t listen(int backlog = 1);
69-
7062
/** Accepts a connection on a TCP socket
7163
*
7264
* The server socket must be bound and set to listen for connections.
@@ -81,51 +73,9 @@ class TCPServer : public InternetSocket {
8173
* @param address Destination for the remote address or NULL
8274
* @return 0 on success, negative error code on failure
8375
*/
76+
MBED_DEPRECATED_SINCE("mbed-os-5.10",
77+
"TCPServer::accept() is deprecated, use Socket *Socket::accept() instead")
8478
nsapi_error_t accept(TCPSocket *connection, SocketAddress *address = NULL);
85-
86-
/** Not supported on TCPServer.
87-
* @param address unused
88-
* @return NSAPI_ERROR_UNSUPPORTED
89-
*/
90-
virtual nsapi_error_t connect(const SocketAddress &address);
91-
92-
/** Not supported on TCPServer.
93-
* @param data unused
94-
* @param size unused
95-
* @return NSAPI_ERROR_UNSUPPORTED
96-
*/
97-
virtual nsapi_size_or_error_t send(const void *data, nsapi_size_t size);
98-
99-
/** Not supported on TCPServer.
100-
* @param data unused
101-
* @param size unused
102-
* @return NSAPI_ERROR_UNSUPPORTED
103-
*/
104-
virtual nsapi_size_or_error_t recv(void *data, nsapi_size_t size);
105-
106-
/** Not supported on TCPServer.
107-
* @param address unused
108-
* @param data unused
109-
* @param size unused
110-
* @return NSAPI_ERROR_UNSUPPORTED
111-
*/
112-
virtual nsapi_size_or_error_t sendto(const SocketAddress& address, const void *data, nsapi_size_t size);
113-
114-
/** Not supported on TCPServer.
115-
* @param address unused
116-
* @param data unused
117-
* @param size unused
118-
* @return NSAPI_ERROR_UNSUPPORTED
119-
*/
120-
virtual nsapi_size_or_error_t recvfrom(SocketAddress* address, void *data, nsapi_size_t size);
121-
122-
protected:
123-
virtual nsapi_protocol_t get_proto();
124-
virtual void event();
125-
126-
volatile unsigned _pending;
127-
rtos::Semaphore _accept_sem;
12879
};
12980

130-
13181
#endif

0 commit comments

Comments
 (0)