Skip to content

Commit

Permalink
rename to (dds_)network_adapter_watcher
Browse files Browse the repository at this point in the history
  • Loading branch information
maloel committed Sep 10, 2024
1 parent 9a59472 commit 965908c
Show file tree
Hide file tree
Showing 7 changed files with 64 additions and 60 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
// Copyright(c) 2024 Intel Corporation. All Rights Reserved.
#pragma once

#include <rsutils/os/adapter-watcher.h>
#include <rsutils/os/network-adapter-watcher.h>
#include <set>
#include <string>

Expand All @@ -11,26 +11,26 @@ namespace realdds {


namespace detail {
class adapter_watcher_singleton;
class network_adapter_watcher_singleton;
}


// Watch for changes to network adapter IPs
//
// Unlike rsutils::os::adapter_watcher, we only call the callbacks when actual changes to IPs are made, which can
// sometimes be seconds after adapter-change notifications are sent
// Unlike rsutils::os::network_adapter_watcher, we only call the callbacks when actual changes to IPs are made, which
// can sometimes be seconds after adapter-change notifications are sent
//
// All you have to do is create a watcher and keep a pointer to it to get notifications
//
class dds_adapter_watcher
class dds_network_adapter_watcher
{
std::shared_ptr< detail::adapter_watcher_singleton > _singleton;
std::shared_ptr< detail::network_adapter_watcher_singleton > _singleton;
rsutils::subscription _subscription;

public:
using callback = std::function< void() >;

dds_adapter_watcher( callback && );
dds_network_adapter_watcher( callback && );

using ip_set = std::set< std::string >;
static ip_set current_ips();
Expand Down
4 changes: 2 additions & 2 deletions third-party/realdds/include/realdds/dds-participant.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ class slice;
namespace realdds {


class dds_adapter_watcher;
class dds_network_adapter_watcher;


// The starting point for any DDS interaction, a participant has a name and is the focal point for creating, destroying,
Expand All @@ -56,7 +56,7 @@ class dds_participant
struct listener_impl;

rsutils::json _settings;
std::shared_ptr< dds_adapter_watcher > _adapter_watcher;
std::shared_ptr< dds_network_adapter_watcher > _adapter_watcher;

public:
dds_participant() = default;
Expand Down
8 changes: 4 additions & 4 deletions third-party/realdds/py/pyrealdds.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
#include <realdds/dds-metadata-syncer.h>
#include <realdds/dds-serialization.h>
#include <realdds/dds-sample.h>
#include <realdds/dds-adapter-watcher.h>
#include <realdds/dds-network-adapter-watcher.h>

#include <rsutils/os/special-folder.h>
#include <rsutils/os/executable-name.h>
Expand Down Expand Up @@ -121,9 +121,9 @@ json load_rs_settings( json const & local_settings )
}


py::list adapter_list()
py::list network_adapter_list()
{
auto const ips = realdds::dds_adapter_watcher::current_ips();
auto const ips = realdds::dds_network_adapter_watcher::current_ips();
py::list obj( ips.size() );
int i = 0;
for( auto & ip : ips )
Expand Down Expand Up @@ -237,7 +237,7 @@ PYBIND11_MODULE(NAME, m) {
m.def( "timestr", []( dds_time t ) { return timestr( t ).to_string(); } );


m.def( "adapter_list", &adapter_list );
m.def( "network_adapter_list", &network_adapter_list );


py::class_< dds_participant::listener,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// License: Apache 2.0. See LICENSE file in root directory.
// Copyright(c) 2024 Intel Corporation. All Rights Reserved.

#include <realdds/dds-adapter-watcher.h>
#include <realdds/dds-network-adapter-watcher.h>
#include <rsutils/shared-ptr-singleton.h>
#include <rsutils/signal.h>
#include <rsutils/easylogging/easyloggingpp.h>
Expand All @@ -14,29 +14,29 @@ using eprosima::fastrtps::rtps::IPFinder;
namespace realdds {


using ip_set = dds_adapter_watcher::ip_set;
using ip_set = dds_network_adapter_watcher::ip_set;


namespace detail {


class adapter_watcher_singleton
class network_adapter_watcher_singleton
{
std::shared_ptr< rsutils::os::adapter_watcher > _adapter_watcher;
std::shared_ptr< rsutils::os::network_adapter_watcher > _adapter_watcher;

ip_set _ips;

std::thread _th;
rsutils::time::stopwatch _time_since_update;

using public_signal
= rsutils::public_signal< adapter_watcher_singleton, ip_set const & /*new*/, ip_set const & /*old*/ >;
= rsutils::public_signal< network_adapter_watcher_singleton, ip_set const & /*new*/, ip_set const & /*old*/ >;

public:
public_signal callbacks;

adapter_watcher_singleton()
: _adapter_watcher( std::make_shared< rsutils::os::adapter_watcher >(
network_adapter_watcher_singleton()
: _adapter_watcher( std::make_shared< rsutils::os::network_adapter_watcher >(
[this]()
{
// Adapters have changed, but we won't see the effects for some time (several seconds)
Expand All @@ -45,7 +45,7 @@ class adapter_watcher_singleton
if( ! _th.joinable() )
{
_th = std::thread(
[this, weak = std::weak_ptr< rsutils::os::adapter_watcher >( _adapter_watcher )]
[this, weak = std::weak_ptr< rsutils::os::network_adapter_watcher >( _adapter_watcher )]
{
LOG_DEBUG( "waiting for IP changes" );
ip_set new_ips, old_ips;
Expand All @@ -70,7 +70,7 @@ class adapter_watcher_singleton
update_ips();
}

~adapter_watcher_singleton()
~network_adapter_watcher_singleton()
{
_adapter_watcher.reset(); // signal the thread to finish
if( _th.joinable() )
Expand All @@ -79,68 +79,72 @@ class adapter_watcher_singleton

void update_ips( ip_set * p_new_ips = nullptr, ip_set * p_old_ips = nullptr )
{
auto ips = dds_adapter_watcher::current_ips();
auto ips = dds_network_adapter_watcher::current_ips();

auto first1 = ips.begin();
auto const last1 = ips.end();
auto first2 = _ips.begin();
auto const last2 = _ips.end();
// Implement a set-difference function
// We can use the fact that a set sorts its items to efficiently do this
// (see https://en.cppreference.com/w/cpp/algorithm/set_difference)
auto new_it = ips.begin();
auto const new_end = ips.end();
auto old_it = _ips.begin();
auto const old_end = _ips.end();

while( first1 != last1 )
while( new_it != new_end )
{
if( first2 == last2 || *first1 < *first2 )
if( old_it == old_end || *new_it < *old_it )
{
// New IP
LOG_DEBUG( "+adapter " << *first1 );
LOG_DEBUG( "+adapter " << *new_it );
if( p_new_ips )
p_new_ips->insert( *first1 );
++first1;
p_new_ips->insert( *new_it );
++new_it;
continue;
}

if( *first2 < *first1 )
if( *old_it < *new_it )
{
// Old IP
LOG_DEBUG( "-adapter " << *first2 );
LOG_DEBUG( "-adapter " << *old_it );
if( p_old_ips )
p_old_ips->insert( *first2 );
++first2;
p_old_ips->insert( *old_it );
++old_it;
continue;
}

++first1;
++first2;
// *new_it == *old_it --> both new and old have this IP
++new_it;
++old_it;
}
while( first2 != last2 )
while( old_it != old_end )
{
// Old IP
LOG_DEBUG( "-adapter " << *first2 );
LOG_DEBUG( "-adapter " << *old_it );
if( p_old_ips )
p_old_ips->insert( *first2 );
++first2;
p_old_ips->insert( *old_it );
++old_it;
}

_ips = std::move( ips );
}
};

static rsutils::shared_ptr_singleton< adapter_watcher_singleton > the_adapter_watcher;
static rsutils::shared_ptr_singleton< network_adapter_watcher_singleton > the_adapter_watcher;


} // namespace detail


dds_adapter_watcher::dds_adapter_watcher( callback && cb )
dds_network_adapter_watcher::dds_network_adapter_watcher( callback && cb )
: _singleton( detail::the_adapter_watcher.instance() ) // keep it alive
, _subscription( _singleton->callbacks.subscribe(
[cb]( ip_set const & new_ips, ip_set const & old_ips ) { cb(); } ) )
{
// As long as someone keeps a pointer to an adapter_watcher, the singleton will be kept alive and it will watch for
// As long as someone keeps a pointer to an network_adapter_watcher, the singleton will be kept alive and it will watch for
// changes; as soon as all instances disappear, the singleton will disappear and the watch should stop.
}


/*static*/ ip_set dds_adapter_watcher::current_ips()
/*static*/ ip_set dds_network_adapter_watcher::current_ips()
{
std::vector< IPFinder::info_IP > local_interfaces;
IPFinder::getIPs( &local_interfaces, false );
Expand Down
4 changes: 2 additions & 2 deletions third-party/realdds/src/dds-participant.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
#include <realdds/dds-guid.h>
#include <realdds/dds-time.h>
#include <realdds/dds-serialization.h>
#include <realdds/dds-adapter-watcher.h>
#include <realdds/dds-network-adapter-watcher.h>

#include <fastdds/dds/domain/DomainParticipantFactory.hpp>
#include <fastdds/dds/domain/DomainParticipantListener.hpp>
Expand Down Expand Up @@ -258,7 +258,7 @@ void dds_participant::init( dds_domain_id domain_id, qos & pqos, rsutils::json c
else
DDS_THROW( runtime_error, "provided settings are invalid: " << settings );

_adapter_watcher = std::make_shared< dds_adapter_watcher >(
_adapter_watcher = std::make_shared< dds_network_adapter_watcher >(
[this]
{
LOG_DEBUG( name() << ": refreshing QoS" );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
namespace rsutils {
namespace os {
namespace detail {
class adapter_watcher_singleton;
class network_adapter_watcher_singleton;
}


Expand All @@ -18,15 +18,15 @@ class adapter_watcher_singleton;
//
// To use, just create a watcher and keep a pointer to it to get notifications. Single callback per instance.
//
class adapter_watcher
class network_adapter_watcher
{
std::shared_ptr< detail::adapter_watcher_singleton > _singleton;
std::shared_ptr< detail::network_adapter_watcher_singleton > _singleton;
subscription _subscription;

public:
using callback = std::function< void() >;

adapter_watcher( callback && );
network_adapter_watcher( callback && );
};


Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// License: Apache 2.0. See LICENSE file in root directory.
// Copyright(c) 2024 Intel Corporation. All Rights Reserved.

#include <rsutils/os/adapter-watcher.h>
#include <rsutils/os/network-adapter-watcher.h>
#include <rsutils/shared-ptr-singleton.h>
#include <rsutils/signal.h>
#include <rsutils/easylogging/easyloggingpp.h>
Expand Down Expand Up @@ -32,9 +32,9 @@ namespace detail {


#if ! defined( __APPLE__ ) && ! defined( __ANDROID__ )
class adapter_watcher_singleton
class network_adapter_watcher_singleton
{
using public_signal = rsutils::public_signal< adapter_watcher_singleton >;
using public_signal = rsutils::public_signal< network_adapter_watcher_singleton >;

#ifdef _WIN32
HANDLE _done;
Expand All @@ -47,7 +47,7 @@ class adapter_watcher_singleton
public:
public_signal callbacks;

adapter_watcher_singleton()
network_adapter_watcher_singleton()
#ifdef _WIN32
: _done( CreateEvent(
nullptr /*security attrs*/, TRUE /*manual reset*/, FALSE /*init unset*/, nullptr /*no name*/ ) )
Expand Down Expand Up @@ -165,7 +165,7 @@ class adapter_watcher_singleton
LOG_DEBUG( "network adapter watcher singleton is up" );
}

~adapter_watcher_singleton()
~network_adapter_watcher_singleton()
{
#ifdef _WIN32
if( _th.joinable() )
Expand Down Expand Up @@ -211,21 +211,21 @@ class adapter_watcher_singleton
};


static rsutils::shared_ptr_singleton< detail::adapter_watcher_singleton > the_adapter_watcher;
static rsutils::shared_ptr_singleton< detail::network_adapter_watcher_singleton > the_adapter_watcher;

#endif // ! __APPLE__ && ! __ANDROID__


} // namespace detail


adapter_watcher::adapter_watcher( callback && cb )
network_adapter_watcher::network_adapter_watcher( callback && cb )
#if ! defined( __APPLE__ ) && ! defined( __ANDROID__ )
: _singleton( detail::the_adapter_watcher.instance() ) // keep it alive
, _subscription( _singleton->callbacks.subscribe( std::move( cb ) ) )
#endif
{
// As long as someone keeps a pointer to an adapter_watcher, the singleton will be kept alive and it will watch for
// As long as someone keeps a pointer to an network_adapter_watcher, the singleton will be kept alive and it will watch for
// changes; as soon as all instances disappear, the singleton will disappear and the watch should stop.
}

Expand Down

0 comments on commit 965908c

Please sign in to comment.