Skip to content

Regression: NetworkEvents::onEvent() can't register function calbacks via lambda expressions #10365

Closed
@vortigont

Description

@vortigont

Board

ESP32 Dev module

Device Description

plain module

Hardware Configuration

plain module

Version

latest master (checkout manually)

IDE Name

PlatformIO

Operating System

Ubuntu Linux

Flash frequency

defajult

PSRAM enabled

no

Upload speed

115200

Description

Network lib has a regression when updated from 3.0.4 to 3.0.5

The method NetworkEvents::onEvent
can no longer register two or more functional callbacks for Network event handling when those are lambda expressions.

In 2f89026 additional code was added that tries to check if an attempt is made to register a duplicate callback function based on determined address of a callback

if (findEvent(cbEvent, event) < cbEventList.size()) {

This template code does not work properly for lambdas and returns 0 (nullptr) always.

template<typename T, typename... U> static size_t getStdFunctionAddress(std::function<T(U...)> f) {
typedef T(fnType)(U...);
fnType **fnPointer = f.template target<fnType *>();
if (fnPointer != nullptr) {
return (size_t)*fnPointer;
}
return (size_t)fnPointer;
}

Do we really need that duplicate callbacks check? It's up to user to register callback, even if those are called twice there is no big deal in that. While that address-pointer comparison magic is tend to errors.

Sketch

#include "Arduino.h"
#include "WiFi.h"

#define MY_SSID    "My_SSID"
#define MY_PASS    "MY_PASSwd"

class MyWiFi{
private:
    wifi_event_id_t eid{999};
    wifi_event_id_t eid2{999};

    // member function for event handling 
    void _onWiFiEvent(arduino_event_id_t event, arduino_event_info_t info){
        Serial.printf( "event tracker1: %d - %s\n", event, Network.eventName(event));
    }

public:
    void reg_events(){
        // use capturing lambda for member function handler
        eid = WiFi.onEvent( [&](WiFiEvent_t event, WiFiEventInfo_t info){ _onWiFiEvent(event, info); } );
        if (eid)
            Serial.printf( "registered hndlr 1 with id:%u\n", eid);
        else
            Serial.println( "Err registering hndlr 1");

        // non-capturing lambda
        eid2 = WiFi.onEvent( [](WiFiEvent_t event, WiFiEventInfo_t info){ Serial.printf( "event tracker2: %d - %s\n", event, Network.eventName(event)); } );
        if (eid2)
            Serial.printf( "registered hndlr 2 with id:%u\n", eid2);
        else
            Serial.println( "Err registering hndlr 2");
    }

};

MyWiFi mywifi;

void setup(){
    Serial.begin(115200);

    mywifi.reg_events();
    WiFi.begin(MY_SSID, MY_PASS);
}


void loop() {}

Debug Message

Log messages with some additional debugging added

[   253][V][NetworkEvents.cpp:227] onEvent(): Check Event dupes, 0 out of 0
registered hndlr 1 with id:1
[   260][V][NetworkEvents.cpp:173] findEvent(): Compare: 0 vs 0
[   268][V][NetworkEvents.cpp:227] onEvent(): Check Event dupes, 0 out of 1
[   275][W][NetworkEvents.cpp:230] onEvent(): Attempt to add duplicate event handler!
Err registering hndlr 2

Other Steps to Reproduce

No response

I have checked existing issues, online documentation and the Troubleshooting Guide

  • I confirm I have checked existing issues, online documentation and Troubleshooting guide.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions