me-no-dev/ESPAsyncTCP

canSend() not working properly

glmnet opened this issue · 2 comments

the problem happens with the ESPAsyncWebServer library using the AsyncEventSource

That component uses canSend() in the implementation, basically checks before calling send() the result of canSend() if it gives false then send() is not called.

Now this library works like this:

  1. add() receives buffer to be appended, this increments a unsent counter of data, and calls a tcp_write method.
  2. send() this calls tcp_output` which does what it has to do and then transfers unset into unacked
  3. tx goes on.... and here commes the funny part
  4. another data comes quickly to be sent, the AsyncEventSource calls add with more data and 1 gets executed, then it checks canSend and 2 is not executed, because canSend() returns false (it checks _pcb_busy)
  5. receiver receives all what was added by 1 and 4 and sends ack for all that data, now the function _ sent is called, here the math tells it to substract what has been acked (in variable len) into the unacked data, but unacked was not incremented and some data is still in unsent, result is, even len > unacked, the unacked is substracted with len, this of course does not result in 0, so _pcb_busy never goes false, the canSend() never returns true, and the connection times out / fails.

This commit glmnet@df6bc86 is a working solution this issue, but I don't know what would be a good solution here, and did not much testing in general.

I understand this is an issue with canSend() mostly, but I haven't done much analysis if this might be causing other connectivity issues

stale commented

[STALE_SET] This issue has been automatically marked as stale because it has not had recent activity. It will be closed in 14 days if no further activity occurs. Thank you for your contributions.

stale commented

[STALE_DEL] This stale issue has been automatically closed. Thank you for your contributions.