Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WiFiServer/WiFiClient] client.available() exhibits blocking behavior #258

Closed
1 task done
redelacruz opened this issue Jul 31, 2024 · 1 comment · Fixed by #259
Closed
1 task done

[WiFiServer/WiFiClient] client.available() exhibits blocking behavior #258

redelacruz opened this issue Jul 31, 2024 · 1 comment · Fixed by #259
Labels
no-issue-activity pending It is a feature/bug-fix request, currently on hold

Comments

@redelacruz
Copy link
Contributor

redelacruz commented Jul 31, 2024

Boards

AMB82-Mini

External Hardware

Other than included JXF37 camera, none.

Hardware Configuration

None

Version

latest main (checkout manually)

IDE Name

VSCode w/ Arduino extension

Operating System

Windows 11

Auto Flash Mode

Disable

Erase All Flash Memory (16MB)

Disable

Standard Lib

Arduino_STD_PRINTF

Upload Speed

2000000

Description

This issue was created in order to create a reference issue for a PR.


When client.stop() is called and then a new client is created soon after, client.connected() == true due to still pending socket close.

In the very commonly used context

while (client.connected()) {
    if (client.available()) {
        // other stuff happens
    }
}

this causes client.available() to block, which it should not do. When writing asynchronous programs, this can cause major issues in timing-sensitive tasks.

Sketch

Requires fix for issue #257 to be applied because of WiFiClient copy assignment.

#include <WiFi.h>

char ssid[] = "";    // your network SSID (name)
char pass[] = "";        // your network password
int status = WL_IDLE_STATUS;
WiFiServer server(80);
WiFiClient client;

void setup()
{
    Serial.begin(115200);
    while (status != WL_CONNECTED) {
        status = WiFi.begin(ssid, pass);
        delay(5000);
    }
  
    server.setNonBlockingMode(); // server is set to NonBlockingMode();
    server.begin();
}

void loop()
{
    client = server.available();
    if (client) {
        Serial.println("new client connected");
        String currentLine = "";
        while (client.connected()) {
            if (client.available()) {
                char c = client.read();
                Serial.write(c);
                if (c == '\n') {
                    if (currentLine.length() == 0) {
                        //do something
                    } else {
                        currentLine = "";
                    }
                } else if (c != '\r') {
                    currentLine += c;
                }
            }
        }
        client.stop();
        Serial.println("client disconnected");
    } else {
        Serial.println("waiting for client connection");
        delay(1000);
    }
}

Error/Debug Message

// ... repeats while no client in non-blocking mode

[ERROR] get_available Accept connection failed
new client connected
client disconnected

[ERROR] get_available Accept connection failed
new client connected
client disconnected

[ERROR] get_available Accept connection failed
new client connected
client disconnected

[INFO] A client connected to this server :
[PORT]: 55775
[IP]:192.168.2.36

new client connected
GET / HTTP/1.1
Host: 192.168.2.172
Connection: keep-alive
Cache-Control: max-age=0
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9,fil;q=0.8
Cookie: __guid=259319114.1308697201864418800.1719734660203.9114

client disconnected

[INFO] A client connected to this server :
[PORT]: 55776
[IP]:192.168.2.36

new client connected

// blocked here by client.available()

Reproduce remarks

Since the client does nothing in the sketch above, the socket can sometimes be closed quickly. But I was able to reproduce this issue reliably on first try or with one or two browser refreshes.

I have checked online documentation, FAQ, GitHub Wiki and existing/closed issues.

  • I confirm I have checked online documentation, FAQ, GitHub Wiki and existing/closed issues.
@redelacruz redelacruz added the pending It is a feature/bug-fix request, currently on hold label Jul 31, 2024
redelacruz added a commit to redelacruz/ambpro2_arduino that referenced this issue Jul 31, 2024
This fixes the broken rule of 3/5/0 in WiFiClient by removing the
unneeded destructor, which caused the socket to stop prematurely on
copy assignment.

It also fixes the blocking behavior caused by `client.available()` by
removing the unneeded `try_again` label and its corresponding `goto`.
In its place, we stop the socket (already pending stop) instead.

Closes Ameba-AIoT#257, Ameba-AIoT#258
Copy link

This issue is stale because it has been open for 14 days with no activity.

M-ichae-l pushed a commit that referenced this issue Oct 8, 2024
* fix: client non-persistent and blocking

This fixes the broken rule of 3/5/0 in WiFiClient by removing the
unneeded destructor, which caused the socket to stop prematurely on
copy assignment.

It also fixes the blocking behavior caused by `client.available()` by
removing the unneeded `try_again` label and its corresponding `goto`.
In its place, we stop the socket (already pending stop) instead.

Closes #257, #258

* Update WiFiClient.cpp

revert: reinstates the try_again label and the relevant goto

This reinstates the `try_again` label and the relevant `goto` statement as requested by @M-ichae-l in comment #r1713128977.

* Update WiFiClient.cpp

feat: stops socket if the client isn't in blocking mode

When `WiFiClient::available()` is called, this stops the socket if `clientdrv.getLastErrno(_sock)` returns `EAGAIN` and the client isn't in blocking mode.

* Update WiFiClient.cpp

* Update release_commit_log.txt
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
no-issue-activity pending It is a feature/bug-fix request, currently on hold
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant