From 9619ec8745cb89f84dd6582d653a7940ef5f838e Mon Sep 17 00:00:00 2001 From: Martino Facchin Date: Fri, 1 Apr 2022 09:46:39 +0200 Subject: [PATCH 1/3] Drastically speedup client.read() operation Since the data being consumed by the reader thread is going to be read somewhere via read() APIs (that are known to be fair and call yield()), we can avoid the delay() when the buffer needs to be flushed by setting the reader thread priority to something lower than the main thread. To be tested on some real world applications (by now, tested with Ethernet/WiFi Client/Server "basic" examples) --- libraries/SocketWrapper/src/MbedClient.cpp | 4 +--- libraries/SocketWrapper/src/MbedClient.h | 2 +- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/libraries/SocketWrapper/src/MbedClient.cpp b/libraries/SocketWrapper/src/MbedClient.cpp index ad1a14cbc..2c82da918 100644 --- a/libraries/SocketWrapper/src/MbedClient.cpp +++ b/libraries/SocketWrapper/src/MbedClient.cpp @@ -21,7 +21,6 @@ void arduino::MbedClient::readSocket() { do { if (rxBuffer.availableForStore() == 0) { yield(); - delay(100); continue; } mutex->lock(); @@ -34,7 +33,6 @@ void arduino::MbedClient::readSocket() { } if (ret == NSAPI_ERROR_WOULD_BLOCK || ret == 0) { yield(); - delay(100); mutex->unlock(); continue; } @@ -71,7 +69,7 @@ void arduino::MbedClient::configureSocket(Socket *_s) { } mutex->lock(); if (reader_th == nullptr) { - reader_th = new rtos::Thread; + reader_th = new rtos::Thread(osPriorityNormal - 2); reader_th->start(mbed::callback(this, &MbedClient::readSocket)); } mutex->unlock(); diff --git a/libraries/SocketWrapper/src/MbedClient.h b/libraries/SocketWrapper/src/MbedClient.h index 07e615cae..a2132ebf3 100644 --- a/libraries/SocketWrapper/src/MbedClient.h +++ b/libraries/SocketWrapper/src/MbedClient.h @@ -73,7 +73,7 @@ class MbedClient : public arduino::Client { int connectSSL(IPAddress ip, uint16_t port); int connectSSL(const char* host, uint16_t port, bool disableSNI = false); size_t write(uint8_t); - size_t write(const uint8_t* buf, size_t size); + size_t write(const uint8_t* buf, size_t size) override; int available(); int read(); int read(uint8_t* buf, size_t size); From 7a11cf03f766143232da3fc867d395030a3865c7 Mon Sep 17 00:00:00 2001 From: Martino Facchin Date: Tue, 5 Apr 2022 11:06:53 +0200 Subject: [PATCH 2/3] SocketWrapper: call close() before mis-reusing connection Some libraries don't call close() and expect the device will do it on its own when the server closes the connection. To fix this, the best thing to do would be either to use connectionKeepAlive() or to simply close() the client before conneting again. For backwards compatibility, let's start from scratch every time connect() is colled twice. --- libraries/SocketWrapper/src/MbedClient.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/libraries/SocketWrapper/src/MbedClient.cpp b/libraries/SocketWrapper/src/MbedClient.cpp index 2c82da918..679889aa4 100644 --- a/libraries/SocketWrapper/src/MbedClient.cpp +++ b/libraries/SocketWrapper/src/MbedClient.cpp @@ -78,6 +78,15 @@ void arduino::MbedClient::configureSocket(Socket *_s) { } int arduino::MbedClient::connect(SocketAddress socketAddress) { + + if (sock && reader_th) { + // trying to reuse a connection, let's call stop() to cleanup the state + char c; + if (sock->recv(&c, 1) < 0) { + stop(); + } + } + if (sock == nullptr) { sock = new TCPSocket(); _own_socket = true; From d30df6d83c54ceee025c808ebedca11a9c17e3c3 Mon Sep 17 00:00:00 2001 From: Martino Facchin Date: Tue, 5 Apr 2022 11:10:02 +0200 Subject: [PATCH 3/3] SocketWrapper: only retry write() if the error is NSAPI_ERROR_WOULD_BLOCK --- libraries/SocketWrapper/src/MbedClient.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/SocketWrapper/src/MbedClient.cpp b/libraries/SocketWrapper/src/MbedClient.cpp index 679889aa4..538005799 100644 --- a/libraries/SocketWrapper/src/MbedClient.cpp +++ b/libraries/SocketWrapper/src/MbedClient.cpp @@ -213,7 +213,7 @@ size_t arduino::MbedClient::write(const uint8_t *buf, size_t size) { int ret = NSAPI_ERROR_WOULD_BLOCK; do { ret = sock->send(buf, size); - } while (ret != size && connected()); + } while ((ret != size && ret == NSAPI_ERROR_WOULD_BLOCK) && connected()); configureSocket(sock); return size; }