mirror of https://github.com/ARMmbed/mbed-os.git
Merge pull request #9424 from SeppoTakalo/ONME-4125
Allows multiple network status listenerspull/9679/head
commit
10bb66a053
|
@ -17,7 +17,8 @@ set(unittest-sources
|
||||||
../features/frameworks/nanostack-libservice/source/libip6string/ip6tos.c
|
../features/frameworks/nanostack-libservice/source/libip6string/ip6tos.c
|
||||||
../features/frameworks/nanostack-libservice/source/libip4string/stoip4.c
|
../features/frameworks/nanostack-libservice/source/libip4string/stoip4.c
|
||||||
../features/frameworks/nanostack-libservice/source/libip6string/stoip6.c
|
../features/frameworks/nanostack-libservice/source/libip6string/stoip6.c
|
||||||
../features/frameworks/nanostack-libservice/source/libBits/common_functions.c
|
../features/frameworks/nanostack-libservice/source/libBits/common_functions.c
|
||||||
|
../features/frameworks/nanostack-libservice/source/libList/ns_list.c
|
||||||
)
|
)
|
||||||
|
|
||||||
# Test files
|
# Test files
|
||||||
|
@ -35,4 +36,5 @@ set(unittest-test-sources
|
||||||
stubs/NetworkStack_stub.cpp
|
stubs/NetworkStack_stub.cpp
|
||||||
stubs/NetworkInterfaceDefaults_stub.cpp
|
stubs/NetworkInterfaceDefaults_stub.cpp
|
||||||
stubs/SocketStats_Stub.cpp
|
stubs/SocketStats_Stub.cpp
|
||||||
|
stubs/mbed_error.c
|
||||||
)
|
)
|
||||||
|
|
|
@ -20,6 +20,7 @@
|
||||||
#include "NetworkStack_stub.h"
|
#include "NetworkStack_stub.h"
|
||||||
|
|
||||||
class stubNetworkInterface : public NetworkInterface {
|
class stubNetworkInterface : public NetworkInterface {
|
||||||
|
public:
|
||||||
virtual nsapi_error_t connect()
|
virtual nsapi_error_t connect()
|
||||||
{
|
{
|
||||||
return NSAPI_ERROR_OK;
|
return NSAPI_ERROR_OK;
|
||||||
|
@ -32,13 +33,22 @@ class stubNetworkInterface : public NetworkInterface {
|
||||||
{
|
{
|
||||||
return &stack;
|
return &stack;
|
||||||
};
|
};
|
||||||
public:
|
virtual void attach(mbed::Callback<void(nsapi_event_t, intptr_t)> cb)
|
||||||
|
{
|
||||||
|
status_cb = cb;
|
||||||
|
}
|
||||||
|
void event(nsapi_event_t e, intptr_t i)
|
||||||
|
{
|
||||||
|
status_cb(e, i);
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
mbed::Callback<void(nsapi_event_t, intptr_t)> status_cb;
|
||||||
NetworkStackstub stack;
|
NetworkStackstub stack;
|
||||||
};
|
};
|
||||||
|
|
||||||
class TestNetworkInterface : public testing::Test {
|
class TestNetworkInterface : public testing::Test {
|
||||||
protected:
|
protected:
|
||||||
NetworkInterface *iface;
|
stubNetworkInterface *iface;
|
||||||
|
|
||||||
virtual void SetUp()
|
virtual void SetUp()
|
||||||
{
|
{
|
||||||
|
@ -131,4 +141,79 @@ TEST_F(TestNetworkInterface, set_blocking)
|
||||||
EXPECT_EQ(iface->set_blocking(true), NSAPI_ERROR_UNSUPPORTED);
|
EXPECT_EQ(iface->set_blocking(true), NSAPI_ERROR_UNSUPPORTED);
|
||||||
}
|
}
|
||||||
|
|
||||||
// No way to test attach as it doesn't do or return anything.
|
void my_iface_callback(nsapi_event_t e, intptr_t i)
|
||||||
|
{
|
||||||
|
(void)e;
|
||||||
|
(void)i;
|
||||||
|
callback_is_called = true;
|
||||||
|
}
|
||||||
|
static bool second_callback_called;
|
||||||
|
void my_iface_callback2(nsapi_event_t e, intptr_t i)
|
||||||
|
{
|
||||||
|
(void)e;
|
||||||
|
(void)i;
|
||||||
|
second_callback_called = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(TestNetworkInterface, add_event_listener)
|
||||||
|
{
|
||||||
|
callback_is_called = false;
|
||||||
|
second_callback_called = false;
|
||||||
|
iface->add_event_listener(my_iface_callback);
|
||||||
|
iface->event(NSAPI_EVENT_CONNECTION_STATUS_CHANGE, 0);
|
||||||
|
EXPECT_EQ(callback_is_called, true);
|
||||||
|
|
||||||
|
iface->remove_event_listener(my_iface_callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(TestNetworkInterface, remove_event_listener)
|
||||||
|
{
|
||||||
|
// Add two callback and check that both are called
|
||||||
|
callback_is_called = false;
|
||||||
|
second_callback_called = false;
|
||||||
|
iface->add_event_listener(my_iface_callback);
|
||||||
|
iface->add_event_listener(my_iface_callback2);
|
||||||
|
iface->event(NSAPI_EVENT_CONNECTION_STATUS_CHANGE, 0);
|
||||||
|
EXPECT_EQ(callback_is_called, true);
|
||||||
|
EXPECT_EQ(second_callback_called, true);
|
||||||
|
|
||||||
|
// Remove one of the callbacks
|
||||||
|
iface->remove_event_listener(my_iface_callback2);
|
||||||
|
callback_is_called = false;
|
||||||
|
second_callback_called = false;
|
||||||
|
|
||||||
|
// expect only the one is called which remains in the list
|
||||||
|
iface->event(NSAPI_EVENT_CONNECTION_STATUS_CHANGE, 0);
|
||||||
|
EXPECT_EQ(callback_is_called, true);
|
||||||
|
EXPECT_EQ(second_callback_called, false);
|
||||||
|
|
||||||
|
// Remove also the last callback, and expect nothing is called
|
||||||
|
iface->remove_event_listener(my_iface_callback);
|
||||||
|
callback_is_called = false;
|
||||||
|
second_callback_called = false;
|
||||||
|
iface->event(NSAPI_EVENT_CONNECTION_STATUS_CHANGE, 0);
|
||||||
|
EXPECT_EQ(callback_is_called, false);
|
||||||
|
EXPECT_EQ(second_callback_called, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(TestNetworkInterface, correct_event_listener_per_interface)
|
||||||
|
{
|
||||||
|
stubNetworkInterface *iface2 = new stubNetworkInterface();
|
||||||
|
iface->add_event_listener(my_iface_callback);
|
||||||
|
iface2->add_event_listener(my_iface_callback2);
|
||||||
|
|
||||||
|
callback_is_called = false;
|
||||||
|
second_callback_called = false;
|
||||||
|
iface->event(NSAPI_EVENT_CONNECTION_STATUS_CHANGE, 0);
|
||||||
|
EXPECT_EQ(callback_is_called, true);
|
||||||
|
EXPECT_EQ(second_callback_called, false);
|
||||||
|
|
||||||
|
callback_is_called = false;
|
||||||
|
second_callback_called = false;
|
||||||
|
iface2->event(NSAPI_EVENT_CONNECTION_STATUS_CHANGE, 0);
|
||||||
|
EXPECT_EQ(callback_is_called, false);
|
||||||
|
EXPECT_EQ(second_callback_called, true);
|
||||||
|
|
||||||
|
iface->remove_event_listener(my_iface_callback);
|
||||||
|
iface2->remove_event_listener(my_iface_callback2);
|
||||||
|
}
|
||||||
|
|
|
@ -12,7 +12,8 @@ set(unittest-sources
|
||||||
../features/frameworks/nanostack-libservice/source/libip6string/ip6tos.c
|
../features/frameworks/nanostack-libservice/source/libip6string/ip6tos.c
|
||||||
../features/frameworks/nanostack-libservice/source/libip4string/stoip4.c
|
../features/frameworks/nanostack-libservice/source/libip4string/stoip4.c
|
||||||
../features/frameworks/nanostack-libservice/source/libip6string/stoip6.c
|
../features/frameworks/nanostack-libservice/source/libip6string/stoip6.c
|
||||||
../features/frameworks/nanostack-libservice/source/libBits/common_functions.c
|
../features/frameworks/nanostack-libservice/source/libBits/common_functions.c
|
||||||
|
../features/frameworks/nanostack-libservice/source/libList/ns_list.c
|
||||||
)
|
)
|
||||||
|
|
||||||
# Test files
|
# Test files
|
||||||
|
@ -27,4 +28,5 @@ set(unittest-test-sources
|
||||||
features/netsocket/NetworkInterface/test_NetworkInterface.cpp
|
features/netsocket/NetworkInterface/test_NetworkInterface.cpp
|
||||||
stubs/NetworkInterfaceDefaults_stub.cpp
|
stubs/NetworkInterfaceDefaults_stub.cpp
|
||||||
stubs/SocketStats_Stub.cpp
|
stubs/SocketStats_Stub.cpp
|
||||||
|
stubs/mbed_error.c
|
||||||
)
|
)
|
||||||
|
|
|
@ -87,3 +87,6 @@ nsapi_error_t NetworkInterface::gethostbyname_async_cancel(int id)
|
||||||
return NSAPI_ERROR_UNSUPPORTED;
|
return NSAPI_ERROR_UNSUPPORTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NetworkInterface::~NetworkInterface()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
|
||||||
|
int mbed_error(int error_status, const char *error_msg, unsigned int error_value, const char *filename, int line_number)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -96,6 +96,9 @@ typedef struct ns_list {
|
||||||
* always assign returned entry pointers to a properly typed pointer variable.
|
* always assign returned entry pointers to a properly typed pointer variable.
|
||||||
* This assignment will be then type-checked where the compiler supports it, and
|
* This assignment will be then type-checked where the compiler supports it, and
|
||||||
* will dereference correctly on compilers that don't support this extension.
|
* will dereference correctly on compilers that don't support this extension.
|
||||||
|
*
|
||||||
|
* If you need to support C++03 compilers that cannot return properly-typed
|
||||||
|
* pointers, such as IAR 7, you need to use NS_LIST_TYPECOERCE to force the type.
|
||||||
* ~~~
|
* ~~~
|
||||||
* NS_LIST_HEAD(example_entry_t, link) my_list;
|
* NS_LIST_HEAD(example_entry_t, link) my_list;
|
||||||
*
|
*
|
||||||
|
@ -199,6 +202,27 @@ union \
|
||||||
#define NS_LIST_TYPECAST_(list, val) (0 ? (list)->type : (val))
|
#define NS_LIST_TYPECAST_(list, val) (0 ? (list)->type : (val))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/** \brief Macro to force correct type if necessary.
|
||||||
|
*
|
||||||
|
* In C, doesn't matter if NS_LIST_TYPECAST_ works or not, as it's legal
|
||||||
|
* to assign void * to a pointer. In C++, we can't do that, so need
|
||||||
|
* a back-up plan for C++03. This forces the type, so breaks type-safety -
|
||||||
|
* only activate when needed, meaning we still get typechecks on other
|
||||||
|
* toolchains.
|
||||||
|
*
|
||||||
|
* If a straight assignment of a ns_list function to a pointer fails
|
||||||
|
* on a C++03 compiler, use the following construct. This will not be
|
||||||
|
* required with C++11 compilers.
|
||||||
|
* ~~~
|
||||||
|
* type *elem = NS_LIST_TYPECOERCE(type *, ns_list_get_first(list));
|
||||||
|
* ~~~
|
||||||
|
*/
|
||||||
|
#if defined(NS_LIST_PTR_TYPE_) || !defined(__cplusplus)
|
||||||
|
#define NS_LIST_TYPECOERCE(type, val) (val)
|
||||||
|
#else
|
||||||
|
#define NS_LIST_TYPECOERCE(type, val) (type) (val)
|
||||||
|
#endif
|
||||||
|
|
||||||
/** \brief Internal macro to check types of input entry pointer. */
|
/** \brief Internal macro to check types of input entry pointer. */
|
||||||
#define NS_LIST_TYPECHECK_(list, entry) \
|
#define NS_LIST_TYPECHECK_(list, entry) \
|
||||||
(NS_PTR_MATCH_((list)->type, (entry), "incorrect entry type for list"), (entry))
|
(NS_PTR_MATCH_((list)->type, (entry), "incorrect entry type for list"), (entry))
|
||||||
|
@ -480,7 +504,8 @@ typedef struct ns_list_link {
|
||||||
* \param list `(const list_t *)` Pointer to list - evaluated multiple times.
|
* \param list `(const list_t *)` Pointer to list - evaluated multiple times.
|
||||||
*/
|
*/
|
||||||
#define ns_list_foreach(type, e, list) \
|
#define ns_list_foreach(type, e, list) \
|
||||||
for (type *e = ns_list_get_first(list); e; e = ns_list_get_next(list, e))
|
for (type *e = NS_LIST_TYPECOERCE(type *, ns_list_get_first(list)); \
|
||||||
|
e; e = NS_LIST_TYPECOERCE(type *, ns_list_get_next(list, e)))
|
||||||
|
|
||||||
/** \brief Iterate forwards over a list, where user may delete.
|
/** \brief Iterate forwards over a list, where user may delete.
|
||||||
*
|
*
|
||||||
|
@ -500,8 +525,8 @@ typedef struct ns_list_link {
|
||||||
* \param list `(list_t *)` Pointer to list - evaluated multiple times.
|
* \param list `(list_t *)` Pointer to list - evaluated multiple times.
|
||||||
*/
|
*/
|
||||||
#define ns_list_foreach_safe(type, e, list) \
|
#define ns_list_foreach_safe(type, e, list) \
|
||||||
for (type *e = ns_list_get_first(list), *_next##e; \
|
for (type *e = NS_LIST_TYPECOERCE(type *, ns_list_get_first(list)), *_next##e; \
|
||||||
e && (_next##e = ns_list_get_next(list, e), true); e = _next##e)
|
e && (_next##e = NS_LIST_TYPECOERCE(type *, ns_list_get_next(list, e)), true); e = _next##e)
|
||||||
|
|
||||||
/** \brief Iterate backwards over a list.
|
/** \brief Iterate backwards over a list.
|
||||||
*
|
*
|
||||||
|
@ -509,7 +534,8 @@ typedef struct ns_list_link {
|
||||||
* Iterating forwards is *slightly* more efficient.
|
* Iterating forwards is *slightly* more efficient.
|
||||||
*/
|
*/
|
||||||
#define ns_list_foreach_reverse(type, e, list) \
|
#define ns_list_foreach_reverse(type, e, list) \
|
||||||
for (type *e = ns_list_get_last(list); e; e = ns_list_get_previous(list, e))
|
for (type *e = NS_LIST_TYPECOERCE(type *, ns_list_get_last(list)); \
|
||||||
|
e; e = NS_LIST_TYPECOERCE(type *, ns_list_get_previous(list, e)))
|
||||||
|
|
||||||
/** \brief Iterate backwards over a list, where user may delete.
|
/** \brief Iterate backwards over a list, where user may delete.
|
||||||
*
|
*
|
||||||
|
@ -517,8 +543,8 @@ typedef struct ns_list_link {
|
||||||
* Iterating forwards is *slightly* more efficient.
|
* Iterating forwards is *slightly* more efficient.
|
||||||
*/
|
*/
|
||||||
#define ns_list_foreach_reverse_safe(type, e, list) \
|
#define ns_list_foreach_reverse_safe(type, e, list) \
|
||||||
for (type *e = ns_list_get_last(list), *_next##e; \
|
for (type *e = NS_LIST_TYPECOERCE(type *, ns_list_get_last(list)), *_next##e; \
|
||||||
e && (_next##e = ns_list_get_previous(list, e), true); e = _next##e)
|
e && (_next##e = NS_LIST_TYPECOERCE(type *, ns_list_get_previous(list, e)), true); e = _next##e)
|
||||||
|
|
||||||
/** \hideinitializer \brief Count entries on a list
|
/** \hideinitializer \brief Count entries on a list
|
||||||
*
|
*
|
||||||
|
|
|
@ -16,7 +16,10 @@
|
||||||
|
|
||||||
#include "netsocket/NetworkInterface.h"
|
#include "netsocket/NetworkInterface.h"
|
||||||
#include "netsocket/NetworkStack.h"
|
#include "netsocket/NetworkStack.h"
|
||||||
|
#include "platform/Callback.h"
|
||||||
|
#include "platform/mbed_error.h"
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
#include "ns_list.h"
|
||||||
|
|
||||||
|
|
||||||
// Default network-interface state
|
// Default network-interface state
|
||||||
|
@ -77,6 +80,64 @@ nsapi_error_t NetworkInterface::add_dns_server(const SocketAddress &address)
|
||||||
|
|
||||||
void NetworkInterface::attach(mbed::Callback<void(nsapi_event_t, intptr_t)> status_cb)
|
void NetworkInterface::attach(mbed::Callback<void(nsapi_event_t, intptr_t)> status_cb)
|
||||||
{
|
{
|
||||||
|
// Dummy, that needs to be overwritten when inherited, but cannot be removed
|
||||||
|
// because suplied previously and can be referred from binaries.
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef struct iface_eventlist_entry {
|
||||||
|
NetworkInterface *iface;
|
||||||
|
mbed::Callback<void(nsapi_event_t, intptr_t)> status_cb;
|
||||||
|
ns_list_link_t link;
|
||||||
|
} iface_eventlist_entry_t;
|
||||||
|
|
||||||
|
typedef NS_LIST_HEAD(iface_eventlist_entry_t, link) iface_eventlist_t;
|
||||||
|
|
||||||
|
static iface_eventlist_t *get_interface_event_list_head()
|
||||||
|
{
|
||||||
|
static iface_eventlist_t NS_LIST_NAME_INIT(event_list);
|
||||||
|
return &event_list;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void call_all_event_listeners(NetworkInterface *iface, nsapi_event_t event, intptr_t val)
|
||||||
|
{
|
||||||
|
iface_eventlist_t *event_list = get_interface_event_list_head();
|
||||||
|
ns_list_foreach(iface_eventlist_entry_t, entry, event_list) {
|
||||||
|
if (entry->iface == iface) {
|
||||||
|
entry->status_cb(event, val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void NetworkInterface::add_event_listener(mbed::Callback<void(nsapi_event_t, intptr_t)> status_cb)
|
||||||
|
{
|
||||||
|
iface_eventlist_t *event_list = get_interface_event_list_head();
|
||||||
|
iface_eventlist_entry_t *entry = new iface_eventlist_entry_t;
|
||||||
|
entry->iface = this;
|
||||||
|
entry->status_cb = status_cb;
|
||||||
|
ns_list_add_to_end(event_list, entry);
|
||||||
|
attach(mbed::callback(&call_all_event_listeners, this));
|
||||||
|
}
|
||||||
|
|
||||||
|
void NetworkInterface::remove_event_listener(mbed::Callback<void(nsapi_event_t, intptr_t)> status_cb)
|
||||||
|
{
|
||||||
|
iface_eventlist_t *event_list = get_interface_event_list_head();
|
||||||
|
ns_list_foreach_safe(iface_eventlist_entry_t, entry, event_list) {
|
||||||
|
if (entry->status_cb == status_cb && entry->iface == this) {
|
||||||
|
ns_list_remove(event_list, entry);
|
||||||
|
delete entry;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NetworkInterface::~NetworkInterface()
|
||||||
|
{
|
||||||
|
iface_eventlist_t *event_list = get_interface_event_list_head();
|
||||||
|
ns_list_foreach_safe(iface_eventlist_entry_t, entry, event_list) {
|
||||||
|
if (entry->iface == this) {
|
||||||
|
ns_list_remove(event_list, entry);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nsapi_connection_status_t NetworkInterface::get_connection_status() const
|
nsapi_connection_status_t NetworkInterface::get_connection_status() const
|
||||||
|
|
|
@ -43,7 +43,7 @@ class EMACInterface;
|
||||||
class NetworkInterface: public DNS {
|
class NetworkInterface: public DNS {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
virtual ~NetworkInterface() {};
|
virtual ~NetworkInterface();
|
||||||
|
|
||||||
/** Return the default network interface.
|
/** Return the default network interface.
|
||||||
*
|
*
|
||||||
|
@ -251,12 +251,38 @@ public:
|
||||||
*
|
*
|
||||||
* The specified status callback function will be called on status changes
|
* The specified status callback function will be called on status changes
|
||||||
* on the network. The parameters on the callback are the event type and
|
* on the network. The parameters on the callback are the event type and
|
||||||
* event-type dependent reason parameter.
|
* event-type dependent reason parameter. Only one callback can be registered at a time.
|
||||||
|
*
|
||||||
|
* To unregister a callback call with status_cb parameter as a zero.
|
||||||
|
*
|
||||||
|
* *NOTE:* Any callbacks registered with this function will be overwritten if
|
||||||
|
* add_event_listener() API is used.
|
||||||
*
|
*
|
||||||
* @param status_cb The callback for status changes.
|
* @param status_cb The callback for status changes.
|
||||||
*/
|
*/
|
||||||
virtual void attach(mbed::Callback<void(nsapi_event_t, intptr_t)> status_cb);
|
virtual void attach(mbed::Callback<void(nsapi_event_t, intptr_t)> status_cb);
|
||||||
|
|
||||||
|
/** Add event listener for interface.
|
||||||
|
*
|
||||||
|
* This API allows multiple callback to be registered for a single interface.
|
||||||
|
* When first called, internal list of event handlers are created and registered to
|
||||||
|
* interface through attach() API.
|
||||||
|
*
|
||||||
|
* Application may only use attach() or add_event_listener() interface. Mixing usage
|
||||||
|
* of both leads to undefined behavior.
|
||||||
|
*
|
||||||
|
* @param status_cb The callback for status changes.
|
||||||
|
*/
|
||||||
|
void add_event_listener(mbed::Callback<void(nsapi_event_t, intptr_t)> status_cb);
|
||||||
|
|
||||||
|
/** Remove event listener from interface.
|
||||||
|
*
|
||||||
|
* Remove previously added callback from the handler list.
|
||||||
|
*
|
||||||
|
* @param status_cb The callback to unregister.
|
||||||
|
*/
|
||||||
|
void remove_event_listener(mbed::Callback<void(nsapi_event_t, intptr_t)> status_cb);
|
||||||
|
|
||||||
/** Get the connection status.
|
/** Get the connection status.
|
||||||
*
|
*
|
||||||
* @return The connection status (@see nsapi_types.h).
|
* @return The connection status (@see nsapi_types.h).
|
||||||
|
|
|
@ -94,6 +94,7 @@ public:
|
||||||
*/
|
*/
|
||||||
Callback(const Callback<R()> &func)
|
Callback(const Callback<R()> &func)
|
||||||
{
|
{
|
||||||
|
memset(this, 0, sizeof(Callback));
|
||||||
if (func._ops) {
|
if (func._ops) {
|
||||||
func._ops->move(this, &func);
|
func._ops->move(this, &func);
|
||||||
}
|
}
|
||||||
|
@ -718,6 +719,7 @@ public:
|
||||||
*/
|
*/
|
||||||
Callback(const Callback<R(A0)> &func)
|
Callback(const Callback<R(A0)> &func)
|
||||||
{
|
{
|
||||||
|
memset(this, 0, sizeof(Callback));
|
||||||
if (func._ops) {
|
if (func._ops) {
|
||||||
func._ops->move(this, &func);
|
func._ops->move(this, &func);
|
||||||
}
|
}
|
||||||
|
@ -1343,6 +1345,7 @@ public:
|
||||||
*/
|
*/
|
||||||
Callback(const Callback<R(A0, A1)> &func)
|
Callback(const Callback<R(A0, A1)> &func)
|
||||||
{
|
{
|
||||||
|
memset(this, 0, sizeof(Callback));
|
||||||
if (func._ops) {
|
if (func._ops) {
|
||||||
func._ops->move(this, &func);
|
func._ops->move(this, &func);
|
||||||
}
|
}
|
||||||
|
@ -1969,6 +1972,7 @@ public:
|
||||||
*/
|
*/
|
||||||
Callback(const Callback<R(A0, A1, A2)> &func)
|
Callback(const Callback<R(A0, A1, A2)> &func)
|
||||||
{
|
{
|
||||||
|
memset(this, 0, sizeof(Callback));
|
||||||
if (func._ops) {
|
if (func._ops) {
|
||||||
func._ops->move(this, &func);
|
func._ops->move(this, &func);
|
||||||
}
|
}
|
||||||
|
@ -2596,6 +2600,7 @@ public:
|
||||||
*/
|
*/
|
||||||
Callback(const Callback<R(A0, A1, A2, A3)> &func)
|
Callback(const Callback<R(A0, A1, A2, A3)> &func)
|
||||||
{
|
{
|
||||||
|
memset(this, 0, sizeof(Callback));
|
||||||
if (func._ops) {
|
if (func._ops) {
|
||||||
func._ops->move(this, &func);
|
func._ops->move(this, &func);
|
||||||
}
|
}
|
||||||
|
@ -3224,6 +3229,7 @@ public:
|
||||||
*/
|
*/
|
||||||
Callback(const Callback<R(A0, A1, A2, A3, A4)> &func)
|
Callback(const Callback<R(A0, A1, A2, A3, A4)> &func)
|
||||||
{
|
{
|
||||||
|
memset(this, 0, sizeof(Callback));
|
||||||
if (func._ops) {
|
if (func._ops) {
|
||||||
func._ops->move(this, &func);
|
func._ops->move(this, &func);
|
||||||
}
|
}
|
||||||
|
|
|
@ -89,10 +89,11 @@ multicast
|
||||||
multicasts
|
multicasts
|
||||||
singleshot
|
singleshot
|
||||||
multishot
|
multishot
|
||||||
_doxy_
|
|
||||||
sa
|
sa
|
||||||
tparam
|
tparam
|
||||||
retarget
|
retarget
|
||||||
TCPSocket
|
TCPSocket
|
||||||
UDPSocket
|
UDPSocket
|
||||||
Socket
|
Socket
|
||||||
|
unregister
|
||||||
|
_doxy_
|
Loading…
Reference in New Issue