-
-
Notifications
You must be signed in to change notification settings - Fork 216
SocketWrapper MbedClient debugging readSocket #912
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
base: main
Are you sure you want to change the base?
Conversation
|
Hi @JAndrassy, I agree with the changes you made for point 1. |
|
@andreagilardoni so should we add everywhere to
I didn't look in the source but I think the unconnected socket still counts as used one from socket-max |
|
I think the only method missing the check for The changes on lines 123:124 are necessary. I only need to understand why you performed changes on |
|
00b5add to
a5fc13f
Compare
|
changes:
|
444339a to
00bc011
Compare
|
@JAndrassy after looking at that everything seems ok, I need to try to run some examples and then I think we can merge this PR. I like how you reorganized the thread function, thanks for your contribution! |
00bc011 to
a40c63f
Compare
|
There is one more problem with the readSocket thread, but if I patch the solution in, it screams for a rewrite of the whole inner loop. the problem is that on err < 0 the thread ends. it can be just that the peer closed the connection. on a new |
|
I quickly tested this PR and I don't see any issues with this. About the other issue you are describing, what |
|
sorry ret not err |
|
If the peer closed the connection than, I think, it is expected that the socket has to be closed and needs to be restarted. In connect I can see that this check is performed ArduinoCore-mbed/libraries/SocketWrapper/src/MbedClient.cpp Lines 84 to 89 in 2ece915
Did I get your point? |
|
then it is ok |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried to analyse and test the proposed changes and I have a few comments (I hope you can find them meaningful).
One thing I found really confusing is the use of the _status flag which is set / reset in a lot of different places (and this make difficult to understand the underling logic).
In the readSocket() thread is appears that is not really necessary to set _status=true at the end of each innermost do-while cicle.
There is no need to set _status=true after the call of the configureSocket() function since is the configureSocket() function itself sets _status=true;. This happens twice: in the connect() and the connectSSL() function.
As additional simplification I would reset _status to false at the beginning of those 2 functions (if all goes well the configureSocket() function will set it to true and in case of problem it will remain set to false removing the need of setting if to false in case of errors). This removes the need to set _status to false in case of problem and ensure it is false if something wrong happened.
About the mutex lock/unlock in the write() function, my understanding is that the mutex is used to prevent access to the rxBuffer from different threads, so it appears to be not necessary here. One point that is certainly wrong is that the changes removed the check about the sock pointer: it is necessary to reintroduce here the check
if (sock == nullptr) {
return 0;
}
this is very important because a user can call write() with an invalid sock and this would crash the program.
Since the mutex is used to prevent "common" access to rxBuffer I noticed that the peek() function that uses rxBuffer is unprotected: I would add the mutex lock/unlock mechanism to the peek() function.
A possible improvement is related to the setSocket() function: this function is called when client is create by a server. However the server allocates a Socket only if there is an incoming request, in case no request is made the server will always call setSocket(nullptr) (please check the EthernetServer::available() function in the EthernetServer.cpp file and verify if my understanding is correct).
In case like this it is probably pointless to call configureSocket() so I would add a check and execute the body of the function only if _sock is different from nullptr.
My last remark is more a doubt: in the connect() and connectSSL() function almost at the end of the function in case ret is not 1 it has been added the statement sock->close(), but this only closes the Socket. Would not be better to call directly the MbedClient stop() function? This would reset all the variables held by the client and not only "close the socket".
|
I avoid doing unnecessary changes in my PR. Where would I stop if I begin to cleanup the code. So I don't even start. So the superfluous The readSocket() function runs in a separate thread so it can't switch _status to false if it isn't definitive. I can remove the lock from write. (btw if socket is null, then mutex is null too) yes. peek() needs the lock. I add it.
as I understand it, the idea is that the socket can be reused for next try to connect, that is why it is not deleted. calling stop() would delete it. all other fields are not initialized because configureSocket didn't run |
a40c63f to
dbe0b07
Compare
dbe0b07 to
3428d75
Compare
I made these changes ^^^ |
|
Maybe this patch could help fixing #937 ? |
| do { | ||
| mutex->lock(); | ||
| if (sock != nullptr && rxBuffer.availableForStore() == 0) { | ||
| if (sock == nullptr) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this subject to the same issues as "Another racy example" here: https://queue.acm.org/detail.cfm?id=2088916? sock is loop invariant but changed in another thread. mutex is the same isn't it?
|
Just throwing #1067 here. Queries to the Arduino Opta hang for ~100ms due to |
In
connectwe have to delete the socket object, because all other functions test it for null and then use mutex which is null, because configureSocket was not invoked. And there are too few sockets in total.In
readSocketthe condition of the inner loop was always true and the inner loop never exited to wait for event or timeout on event. The inner loop only paused for yield(). With the PR if no data are available the inner loop doesbreakto outer loop where the thread waits for event or timeout.3) I think we have to do mutex inwritetoo