1
0
mirror of https://github.com/esp8266/Arduino.git synced 2025-04-19 23:22:16 +03:00

fix #1002 ::Flush() wait for empty send buffer (#3967)

* fix #1002 ::Flush() wait for empty send buffer

* WiFiClient::Flush() guarantees that the data has been delivered
option 1 of https://github.com/esp8266/Arduino/pull/3967#discussion_r156901071
10ms max wait according to loaded tcp echo/reply scheme
This commit is contained in:
david gauchard 2017-12-17 17:16:41 +01:00 committed by Develo
parent affd1b37b8
commit 26980b39e3
5 changed files with 30 additions and 7 deletions

View File

@ -259,7 +259,7 @@ size_t WiFiClient::peekBytes(uint8_t *buffer, size_t length) {
void WiFiClient::flush() void WiFiClient::flush()
{ {
if (_client) if (_client)
_client->flush(); _client->wait_until_sent();
} }
void WiFiClient::stop() void WiFiClient::stop()

View File

@ -243,8 +243,7 @@ int WiFiUDP::peek()
void WiFiUDP::flush() void WiFiUDP::flush()
{ {
if (_ctx) endPacket();
_ctx->flush();
} }
IPAddress WiFiUDP::remoteIP() IPAddress WiFiUDP::remoteIP()

View File

@ -107,7 +107,7 @@ public:
if(this != 0) { if(this != 0) {
DEBUGV(":ur %d\r\n", _refcnt); DEBUGV(":ur %d\r\n", _refcnt);
if(--_refcnt == 0) { if(--_refcnt == 0) {
flush(); discard_received();
close(); close();
if(_discard_cb) { if(_discard_cb) {
_discard_cb(_discard_cb_arg, this); _discard_cb(_discard_cb_arg, this);
@ -277,7 +277,7 @@ public:
return copy_size; return copy_size;
} }
void flush() void discard_received()
{ {
if(!_rx_buf) { if(!_rx_buf) {
return; return;
@ -290,6 +290,22 @@ public:
_rx_buf_offset = 0; _rx_buf_offset = 0;
} }
void wait_until_sent()
{
// fix option 1 in
// https://github.com/esp8266/Arduino/pull/3967#pullrequestreview-83451496
// TODO: option 2
#define WAIT_TRIES_MS 10 // at most 10ms
int tries = 1+ WAIT_TRIES_MS;
while (state() == ESTABLISHED && tcp_sndbuf(_pcb) != TCP_SND_BUF && --tries) {
_write_some();
delay(1); // esp_ schedule+yield
}
}
uint8_t state() const uint8_t state() const
{ {
if(!_pcb) { if(!_pcb) {

View File

@ -118,7 +118,7 @@ size_t EthernetUDP::write(const uint8_t *buffer, size_t size)
int EthernetUDP::parsePacket() int EthernetUDP::parsePacket()
{ {
// discard any remaining bytes in the last packet // discard any remaining bytes in the last packet
flush(); clear_remaining();
if (recvAvailable(_sock) > 0) if (recvAvailable(_sock) > 0)
{ {
@ -204,7 +204,7 @@ int EthernetUDP::peek()
return b; return b;
} }
void EthernetUDP::flush() void EthernetUDP::clear_remaining()
{ {
// could this fail (loop endlessly) if _remaining > 0 and recv in read fails? // could this fail (loop endlessly) if _remaining > 0 and recv in read fails?
// should only occur if recv fails after telling us the data is there, lets // should only occur if recv fails after telling us the data is there, lets
@ -216,3 +216,8 @@ void EthernetUDP::flush()
} }
} }
void EthernetUDP::flush()
{
endPacket();
}

View File

@ -50,6 +50,9 @@ private:
uint16_t _offset; // offset into the packet being sent uint16_t _offset; // offset into the packet being sent
uint16_t _remaining; // remaining bytes of incoming packet yet to be processed uint16_t _remaining; // remaining bytes of incoming packet yet to be processed
protected:
void clear_remaining();
public: public:
EthernetUDP(); // Constructor EthernetUDP(); // Constructor
virtual uint8_t begin(uint16_t); // initialize, start listening on specified port. Returns 1 if successful, 0 if there are no sockets available to use virtual uint8_t begin(uint16_t); // initialize, start listening on specified port. Returns 1 if successful, 0 if there are no sockets available to use