me-no-dev / ESPAsyncWebServer

Async Web Server for ESP8266 and ESP32
3.67k stars 1.21k forks source link

How does asyncronous WebSocket really works? #814

Closed gnalbandian closed 3 years ago

gnalbandian commented 4 years ago

Hi everyone.

I'm having some issues while using the library that has to do with the way that asynchronous works.

I my loop() function I'm calling another function (let's call it UpdateObjs) that does some stuff with some objects i have, only if the object id is different from "-1". This objects are represented in a html webpage where the user can interact with them. One of the things the user can do, is to delete the object which would result in setting the object id variable to "-1" (no delete nor new for deleting/creating objects, all memory is statically allocated at boot), and also would set some other object's pointers back to nullptr.

Commands from the user and data updated from the ESP8266 is sent through websockets. What's happening, and I don't know how, is that sometimes while the program is inside UpdateObjs function, the user 'deletes' the object that's currently used by the UpdateObjs, setting its id to "-1" and assigning some objects pointer to nullptr causing the program to crash due to null pointer reference.

My concern is, how does ws.onEvent(onEvent) callback works so as to modify objects data while the program is in the middle of UpdateObjs? I believed that there was only one function called at a time, what would protect the data that's being used from deletion while in use.

class ExampleObject
{
    public:

    void deleteObj() 
    {
        _id = -1;
        _sensor = nullptr;
    }
    //....
    //other functions
    //....
    int8_t getId() {return _id;}
    OtherClassObject* _sensor;

    private:
    int8_t _id;

} exampleObj;

The problem happens while:

while(exampleObj->getId() != -1)
{
    exampleObj->_sensor.read();
    ....
}

but _sensor is gone now.

Can someone enlightem me?

zekageri commented 4 years ago

I belive that the issue is when you try to reach a memory space from two different cores. Async means that the events happening on the other core. So if your function is on core 1, and want to modify a variable from there, meanwhile you get an event at the core 0 and try to modify the same variable what the core 1 is currently modifiing then bumm error.

Correct me if i'am wrong.

gnalbandian commented 4 years ago

Sorry, I forgot to mention that this development run on a ESP8266. So no dual core, just single core. Nonetheless this library runs in async mode, and I just cant figure out how it does it. I imagine that at some point i the background the library does it{s stuff, but cannot figure out how or where nor when.

zekageri commented 4 years ago

On a single core chip, the async part is really just not using delay. It is solved with the millis() function. When you using a websocket library i belive that you have to call some kind of a handler function inside loop to handle the socket events. So no way for the two functions to modify the same variable at the same time.

I think you forgot to mention something. Do you really modifing the class that is exist on the memory? Do you have just one class? Or you have multiple classes in an array and you refer to it with array index?

stale[bot] commented 3 years ago

[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[bot] commented 3 years ago

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