-
Notifications
You must be signed in to change notification settings - Fork 129
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
Rework socket buffer layer to prevent/reduce locks up #204
Rework socket buffer layer to prevent/reduce locks up #204
Conversation
Attempt to read socket data from the WINC1500 buffers (over SPI) instead of buffering in MCU.
…ocket book keeping
If all it’s data was not read.
Hi @klausj1, if you have some time if would be great if you can test this and provide your feedback. I think it fixes #182. I think the sends were being blocked because there was some pending recv data from the WINC1500. The timeout you proposed in #202 is effective but this will fail the write if there is a partial recv pending and the write has no buffers available. |
3c3c93a
to
05ad096
Compare
05ad096
to
1944d03
Compare
@drp0 has tested this an confirms it improves stability with #36 in #36 (comment) |
@sandeepmistry, yes, I will do a test. Latest after christmas, hopefully before. I assume #180 should also be solved, correct? |
@sandeepmistry, OK, I did a quick test just now:
Test with sandeepmistry:socket-buffer-winc1500:
The good thing is that it seems to be 100% reproducable, no need to wait for hours or days. I'll try to make a reduced sketch, or do you have a better idea? Klaus |
Some more info: The problem was not that the HTTP-Request from the second client was not answered, but with the new library the request takes >30 seconds, with the old one it takes <4 seconds. And I only wait for 10 seconds before I assume that there is no answer. So the above behaviour should be easily reproducable by fetching a not too small website with HTTP get (I use http://wetter.orf.at/burgenland/), and disconnecting the WIFI while data are still pending. I read the data with
Do you need a reduced sketch, or is this info enough? Klaus |
This unblocks the hif_recv if there was any pending socket data.
Thanks, now the disconnect works. |
I made a testprogram showing that HTTP get is 10 times slower, and that a call to a second WiFi-Client still does not deliver data (client does not get available) if there is unread data from the first WiFi-Client (I am not sure if this behavioud is intended with this version or not, probably it is intended). The sketch does 4 tests:
With the original 0.14.5-version, already the second test "hangs" - WiFi.Begin() does not work anymore With the new version, test 4 cannot read data from the second client, either the client does not get available, or (if the client is not connected anymore) connect() does not work. If I call WiFi.disconnect() afterwards and try again, everything works again. I attach the sketch (sketch.zip) and the logfiles for original and new WiFi-Library (logs.zip): Can you fix 10 slow HTTP get-times? I would like to wait for a long-time-test until this is fixed. Regards, |
Hi @hoblins, Thank you for taking the time to test these changes and provide your feedback! If you have a (minimal) sketch to reproduce the |
Hi, with the LED-changes HTTP get is fast again :) After some rework my sketch works again. The behaviour of reading from the socket has changed a little bit, or probably my implementation (copied from some restclient-library) was wrong, but with the old Wifi-Libraries it worked.
This does not work anymore, because while reading the response from HTTP get, the client becomes unavailable for some (typically 3-5) milliseconds, and then comes available again. So I changed my implementation a little bit, and now it works as before the LED-changes, but much faster :) I assume my old implementation was simply not correct. Right? Hopefully not too many people did the same mistake as I did. I'll start a long-time test now. Klaus |
Hi @klausj1, Thanks for trying this again, we'll most likely be merging and releasing these changes in January.
Yes, |
when buffer is empty and recv/recvfrom is called on the socket, makes it a bit less likely WiFiSocketClass::available() returns 0 if data is in the pipeline.
I did a quick test with a modified version of https://github.com/arduino-libraries/WiFi101/blob/master/examples/WiFiWebClient/WiFiWebClient.ino which does a GET to http://arduino.cc/asciilogo.txt
|
As I connect to a private server I would like to avoid spreading the code. If that could help, I could try to minimize the sketch for reading the code and/or generate some log files. |
My sketch is running for ~3 days now, without any problem :) With the original version, it survived just 2-3 hours. One more question: If the buffer is full (e.g. because data from one client are not read yet), and then the WLAN connection goes down, should the automatic disconnect work (i.e., will WiFi.Status() deliver not connected, or will WiFi.Status() still dliver connected, because of the full buffer)? |
Understood, minimal sketch and log files are better than nothing, but would be slower. Any chance you can reproduce the issue with a public server? |
Hi @klausj1,
Excellent news!
On AVR boards it would still return connected until all the data in the queue is processed, so up until the last 64 bytes of the socket data chunk. SAMD boards do that have this issue with these changes. We requested an additional API from Microchip/Atmel to cap the maximum chunk size, but have not heard any news on this. |
With my new router I can't reproduce the error anymore. So I think was some error with my old AVM Fritzbox 7270. |
Yesterday my sketch blocked after ~20 days. I do not have a serial log, but from the LED state I can see that it hangs in reading the time via UDP (code from this function see below, it hangs between I assume it hangs when WLAN is turned off during or shortly before calling this function. The blue WLAN LED on the WLAN shield was on, so somehow the disconnect was not realized. Maybe you have the chance to find something. Here is the code (again, I disconnect the WiFi if I do not get an answer, trying a "self-repair"):
|
@klausj1 please create a new issue to track what you mentioned in #204 (comment). Since this PR is merged it would be easier to track in a new issue. |
Hi Sandeep,
I have just updated to wifi101 v15
I tried to adapt my sketch to get the remote IP using your suggestions from the recent test:
===========================================================================================
In src/WiFi.cpp there the following line:
static void socket_cb(SOCKET sock, uint8 u8Msg, void *pvMsg)
remove the static so it becomes:
void socket_cb(SOCKET sock, uint8 u8Msg, void *pvMsg)
then in your sketch add void socket_cb(SOCKET sock, uint8 u8Msg, void *pvMsg); to forward declare it.
=============================================================================================
The sketch failed to compile with error:
Arduino: 1.8.5 (Windows 7), Board: "Arduino/Genuino Mega or Mega 2560, ATmega2560 (Mega 2560)"
In file included from C:\Users\laptop\Desktop\Documents\Arduino\software\WiFi101ADC2TFT11\WiFi101ADC2TFT11.ino:67:0:
C:\Users\laptop\Documents\Arduino\libraries\WiFi101\src/WiFi101.h: In function 'void myResolve_cb(uint8_t*, uint32_t)':
C:\Users\laptop\Documents\Arduino\libraries\WiFi101\src/WiFi101.h:177:11: error: 'uint32_t WiFiClass::_resolve' is private
uint32_t _resolve;
WiFi101ADC2TFT11:215: error: within this context
WiFi._resolve = hostIp;
C:\Users\laptop\Desktop\Documents\Arduino\software\WiFi101ADC2TFT11\WiFi101ADC2TFT11.ino: In function 'void mySocketBufferCb(SOCKET, uint8, void*)':
WiFi101ADC2TFT11:219: error: 'socketBufferCb' was not declared in this scope
socketBufferCb(sock, u8Msg, pvMsg); // call the original callback
exit status 1
Is there a way forward to regain the remote IP?
Regards,
David
From: Sandeep Mistry [mailto:notifications@github.com]
Sent: 02 January 2018 14:42
To: arduino-libraries/WiFi101
Cc: drp0; Mention
Subject: Re: [arduino-libraries/WiFi101] Rework socket buffer layer to prevent/reduce locks up (#204)
Many thanks for @klausj1 <https://github.com/klausj1> , @hoblins <https://github.com/hoblins> , and @drp0 <https://github.com/drp0> for testing these changes and providing their feedback. These changes will be included in an upcoming WiFi101 library release.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub <#204 (comment)> , or mute the thread <https://github.com/notifications/unsubscribe-auth/ANHAGsD_JAIxRKKH6W96S9LpjtLItPbKks5tGkBBgaJpZM4Q2wDB> .Image removed by sender.
|
I had a bit of time, so I now have the callback working:
String theclient = ""; // callback returned remote ip and port void socket_cb(SOCKET sock, uint8 u8Msg, void *pvMsg); static void myResolve_cb(uint8_t * /* hostName */, uint32_t hostIp) { theclient contains the latest ip and port David |
Discussion from #204 (comment) continued in #212 |
Similar idea to #77 but more focused on preventing/reducing lock ups. On the MKR1000 (or boards with higher RAM), there should be no lock ups now, AVR based boards reduced lock ups.
Related issues: #32, #36, #89, #180, #182.
I think the following PR's can be closed if this is merged, as this will resolve similar issues to them: #200, #202.
Needs thorough testing before merging.