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

WiFiClient: don’t destroy ClientContext on ::stop

Reported in https://github.com/esp8266/Arduino/issues/4078.

WiFiClient::stopAll, called from a WiFi disconnected event handler,
could be called while WiFiClient::connect was in progress. This issue
was initially fixed in #4194, by testing `this` pointer for being
non-null in ClientContext::connect.

This change delegates deletion of ClientContext to WiFiClient
destructor. WiFiClient::stop only calls ClientContext::stop, which
closes/aborts the connection.
This commit is contained in:
Ivan Grokhotkov 2018-02-19 16:29:34 +03:00 committed by Ivan Grokhotkov
parent 28d8a41219
commit ee5a1e2804
3 changed files with 70 additions and 16 deletions

View File

@ -272,8 +272,7 @@ void WiFiClient::stop()
if (!_client) if (!_client)
return; return;
_client->unref(); _client->close();
_client = 0;
} }
uint8_t WiFiClient::connected() uint8_t WiFiClient::connected()

View File

@ -107,7 +107,6 @@ public:
void unref() void unref()
{ {
if(this != 0) {
DEBUGV(":ur %d\r\n", _refcnt); DEBUGV(":ur %d\r\n", _refcnt);
if(--_refcnt == 0) { if(--_refcnt == 0) {
discard_received(); discard_received();
@ -119,7 +118,6 @@ public:
delete this; delete this;
} }
} }
}
int connect(ip_addr_t* addr, uint16_t port) int connect(ip_addr_t* addr, uint16_t port)
{ {
@ -131,13 +129,13 @@ public:
_op_start_time = millis(); _op_start_time = millis();
// This delay will be interrupted by esp_schedule in the connect callback // This delay will be interrupted by esp_schedule in the connect callback
delay(_timeout_ms); delay(_timeout_ms);
// WiFi may have vanished during the delay (#4078) _connect_pending = 0;
if (!this || !_pcb) { if (!_pcb) {
DEBUGV(":vnsh\r\n"); DEBUGV(":cabrt\r\n");
return 0; return 0;
} }
_connect_pending = 0;
if (state() != ESTABLISHED) { if (state() != ESTABLISHED) {
DEBUGV(":ctmo\r\n");
abort(); abort();
return 0; return 0;
} }

View File

@ -0,0 +1,57 @@
#include <Arduino.h>
#include <BSTest.h>
#include <test_config.h>
#include <ESP8266WiFi.h>
#include <Ticker.h>
extern "C" {
#include "user_interface.h"
}
BS_ENV_DECLARE();
void setup()
{
Serial.begin(115200);
Serial.setDebugOutput(true);
WiFi.persistent(false);
WiFi.mode(WIFI_STA);
WiFi.begin(STA_SSID, STA_PASS);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
}
BS_RUN(Serial);
}
static void stopAll()
{
WiFiClient::stopAll();
}
static void disconnectWiFI()
{
wifi_station_disconnect();
}
/* Some IP address that we can try connecting to, and expect a timeout */
#define UNREACHABLE_IP "192.168.255.255"
TEST_CASE("WiFiClient::stopAll during WiFiClient::connect", "[wificlient]")
{
WiFiClient client;
Ticker t;
t.once_ms(500, &stopAll);
REQUIRE(client.connect(UNREACHABLE_IP, 1024) == 0);
}
TEST_CASE("WiFi disconnect during WiFiClient::connect", "[wificlient]")
{
WiFiClient client;
Ticker t;
t.once_ms(500, &disconnectWiFI);
REQUIRE(client.connect(UNREACHABLE_IP, 1024) == 0);
}
void loop()
{
}