Skip to content

Commit

Permalink
PR IntelRealSense#12498 from Eran: context construction using make()
Browse files Browse the repository at this point in the history
  • Loading branch information
maloel authored Dec 11, 2023
2 parents 409e209 + 67ddd5c commit cd2a5ec
Show file tree
Hide file tree
Showing 13 changed files with 104 additions and 50 deletions.
28 changes: 19 additions & 9 deletions src/backend-device-factory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -126,13 +126,18 @@ std::shared_ptr< platform::backend > backend_device::get_backend()
}


backend_device_factory::backend_device_factory( context & ctx, callback && cb )
backend_device_factory::backend_device_factory( std::shared_ptr< context > const & ctx, callback && cb )
: super( ctx )
, _device_watcher( backend_device_watcher.instance() )
, _dtor( _device_watcher->subscribe(
[this, cb = std::move( cb )]( platform::backend_device_group const & old,
platform::backend_device_group const & curr )
[this, liveliness = std::weak_ptr< context >( ctx ), cb = std::move( cb )](
platform::backend_device_group const & old, platform::backend_device_group const & curr )
{
// the factory should be alive as long as the context is alive
auto live_ctx = liveliness.lock();
if( ! live_ctx )
return;

auto old_list = create_devices_from_group( old, RS2_PRODUCT_LINE_ANY );
auto new_list = create_devices_from_group( curr, RS2_PRODUCT_LINE_ANY );

Expand Down Expand Up @@ -166,7 +171,11 @@ backend_device_factory::~backend_device_factory()

std::vector< std::shared_ptr< device_info > > backend_device_factory::query_devices( unsigned requested_mask ) const
{
if( ( requested_mask & RS2_PRODUCT_LINE_SW_ONLY ) || ( _context.get_device_mask() & RS2_PRODUCT_LINE_SW_ONLY ) )
auto ctx = get_context();
if( ! ctx )
return {};

if( ( requested_mask & RS2_PRODUCT_LINE_SW_ONLY ) || ( ctx->get_device_mask() & RS2_PRODUCT_LINE_SW_ONLY ) )
return {}; // We don't carry any software devices

auto backend = _device_watcher->get_backend();
Expand All @@ -181,33 +190,34 @@ std::vector< std::shared_ptr< device_info > > backend_device_factory::query_devi
std::vector< std::shared_ptr< platform::platform_device_info > >
backend_device_factory::create_devices_from_group( platform::backend_device_group devices, int requested_mask ) const
{
auto ctx = get_context();
std::vector< std::shared_ptr< platform::platform_device_info > > list;
unsigned const mask = context::combine_device_masks( requested_mask, _context.get_device_mask() );
unsigned const mask = context::combine_device_masks( requested_mask, ctx->get_device_mask() );
if( ! ( mask & RS2_PRODUCT_LINE_SW_ONLY ) )
{
if( mask & RS2_PRODUCT_LINE_D400 )
{
auto d400_devices = d400_info::pick_d400_devices( _context.shared_from_this(), devices );
auto d400_devices = d400_info::pick_d400_devices( ctx, devices );
std::copy( std::begin( d400_devices ), end( d400_devices ), std::back_inserter( list ) );
}

if( mask & RS2_PRODUCT_LINE_D500 )
{
auto d500_devices = d500_info::pick_d500_devices( _context.shared_from_this(), devices );
auto d500_devices = d500_info::pick_d500_devices( ctx, devices );
std::copy( begin( d500_devices ), end( d500_devices ), std::back_inserter( list ) );
}

// Supported recovery devices
{
auto recovery_devices
= fw_update_info::pick_recovery_devices( _context.shared_from_this(), devices.usb_devices, mask );
= fw_update_info::pick_recovery_devices( ctx, devices.usb_devices, mask );
std::copy( begin( recovery_devices ), end( recovery_devices ), std::back_inserter( list ) );
}

if( mask & RS2_PRODUCT_LINE_NON_INTEL )
{
auto uvc_devices
= platform_camera_info::pick_uvc_devices( _context.shared_from_this(), devices.uvc_devices );
= platform_camera_info::pick_uvc_devices( ctx, devices.uvc_devices );
std::copy( begin( uvc_devices ), end( uvc_devices ), std::back_inserter( list ) );
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/backend-device-factory.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ class backend_device_factory : public device_factory
rsutils::subscription const _dtor; // raii generic code, used to automatically unsubscribe our callback

public:
backend_device_factory( context &, callback && );
backend_device_factory( std::shared_ptr< context > const &, callback && );
~backend_device_factory();

// Query any subset of available devices and return them as device-info objects
Expand Down
20 changes: 16 additions & 4 deletions src/context.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,26 +67,38 @@ namespace librealsense {
version_logged = true;
LOG_DEBUG( "Librealsense VERSION: " << RS2_API_FULL_VERSION_STR );
}
}


void context::create_factories( std::shared_ptr< context > const & sptr )
{
_factories.push_back( std::make_shared< backend_device_factory >(
*this,
sptr,
[this]( std::vector< std::shared_ptr< device_info > > const & removed,
std::vector< std::shared_ptr< device_info > > const & added )
{ invoke_devices_changed_callbacks( removed, added ); } ) );

#ifdef BUILD_WITH_DDS
_factories.push_back( std::make_shared< rsdds_device_factory >(
*this,
sptr,
[this]( std::vector< std::shared_ptr< device_info > > const & removed,
std::vector< std::shared_ptr< device_info > > const & added )
{ invoke_devices_changed_callbacks( removed, added ); } ) );
#endif
}


context::context( char const * json_settings )
: context( json_settings ? json::parse( json_settings ) : json::object() )
/*static*/ std::shared_ptr< context > context::make( json const & settings )
{
std::shared_ptr< context > sptr( new context( settings ) );
sptr->create_factories( sptr );
return sptr;
}


/*static*/ std::shared_ptr< context > context::make( char const * json_settings )
{
return make( json_settings ? json::parse( json_settings ) : json::object() );
}


Expand Down
10 changes: 7 additions & 3 deletions src/context.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,11 +16,15 @@ namespace librealsense
class processing_block_interface;


class context : public std::enable_shared_from_this<context>
class context
{
context( nlohmann::json const & ); // private! use make()

void create_factories( std::shared_ptr< context > const & sptr );

public:
explicit context( nlohmann::json const & );
explicit context( char const * json_settings );
static std::shared_ptr< context > make( nlohmann::json const & );
static std::shared_ptr< context > make( char const * json_settings );

~context();

Expand Down
22 changes: 14 additions & 8 deletions src/dds/rsdds-device-factory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -80,10 +80,10 @@ static std::map< realdds::dds_domain_id, domain_context > domain_context_by_id;
static std::mutex domain_context_by_id_mutex;


rsdds_device_factory::rsdds_device_factory( context & ctx, callback && cb )
rsdds_device_factory::rsdds_device_factory( std::shared_ptr< context > const & ctx, callback && cb )
: super( ctx )
{
nlohmann::json const & dds_settings = rsutils::json::nested( _context.get_settings(), std::string( "dds", 3 ) );
nlohmann::json const & dds_settings = rsutils::json::nested( ctx->get_settings(), std::string( "dds", 3 ) );
if( dds_settings.is_object() && rsutils::json::get( dds_settings, std::string( "enabled", 7 ), true ) )
{
auto domain_id = rsutils::json::get< realdds::dds_domain_id >( dds_settings, std::string( "domain", 6 ), 0 );
Expand All @@ -107,11 +107,15 @@ rsdds_device_factory::rsdds_device_factory( context & ctx, callback && cb )
}
_watcher_singleton = domain.device_watcher.instance( _participant );
_subscription = _watcher_singleton->subscribe(
[this, cb = std::move( cb )]( std::shared_ptr< realdds::dds_device > const & dev, bool added )
[liveliness = std::weak_ptr< context >( ctx ),
cb = std::move( cb )]( std::shared_ptr< realdds::dds_device > const & dev, bool added )
{
// the factory should be alive as long as the context is alive
auto ctx = liveliness.lock();
if( ! ctx )
return;
std::vector< std::shared_ptr< device_info > > infos_added;
std::vector< std::shared_ptr< device_info > > infos_removed;
auto ctx = _context.shared_from_this();
auto dev_info = std::make_shared< dds_device_info >( ctx, dev );
if( added )
infos_added.push_back( dev_info );
Expand All @@ -131,7 +135,7 @@ std::vector< std::shared_ptr< device_info > > rsdds_device_factory::query_device
std::vector< std::shared_ptr< device_info > > list;
if( _watcher_singleton )
{
unsigned const mask = context::combine_device_masks( requested_mask, _context.get_device_mask() );
unsigned const mask = context::combine_device_masks( requested_mask, get_context()->get_device_mask() );

_watcher_singleton->get_device_watcher()->foreach_device(
[&]( std::shared_ptr< realdds::dds_device > const & dev ) -> bool
Expand All @@ -156,9 +160,11 @@ std::vector< std::shared_ptr< device_info > > rsdds_device_factory::query_device
return true;
}

std::shared_ptr< device_info > info
= std::make_shared< dds_device_info >( _context.shared_from_this(), dev );
list.push_back( info );
if( auto ctx = get_context() )
{
std::shared_ptr< device_info > info = std::make_shared< dds_device_info >( ctx, dev );
list.push_back( info );
}
return true; // continue iteration
} );
}
Expand Down
2 changes: 1 addition & 1 deletion src/dds/rsdds-device-factory.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ class rsdds_device_factory : public device_factory
rsutils::subscription _subscription;

public:
rsdds_device_factory( context &, callback && );
rsdds_device_factory( std::shared_ptr< context > const &, callback && );
~rsdds_device_factory();

// Query any subset of available devices and return them as device-info objects
Expand Down
36 changes: 26 additions & 10 deletions src/device_hub.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,27 +11,43 @@ namespace librealsense
{
typedef rs2::devices_changed_callback<std::function<void(rs2::event_information& info)>> hub_devices_changed_callback;

device_hub::device_hub(std::shared_ptr<librealsense::context> ctx, int mask)
device_hub::device_hub( std::shared_ptr< librealsense::context > ctx, int mask )
: _ctx( ctx )
, _mask( mask )
{
_device_list = _ctx->query_devices(mask);
}

void device_hub::init( std::shared_ptr< device_hub > const & sptr )
{
_device_list = _ctx->query_devices( _mask );

_device_change_subscription = _ctx->on_device_changes(
[&, mask]( std::vector< std::shared_ptr< device_info > > const & /*removed*/,
std::vector< std::shared_ptr< device_info > > const & /*added*/ )
[&, liveliness = std::weak_ptr< device_hub >( sptr )](
std::vector< std::shared_ptr< device_info > > const & /*removed*/,
std::vector< std::shared_ptr< device_info > > const & /*added*/ )
{
std::unique_lock< std::mutex > lock( _mutex );
if( auto keepalive = liveliness.lock() )
{
std::unique_lock< std::mutex > lock( _mutex );

_device_list = _ctx->query_devices( mask );
_device_list = _ctx->query_devices( _mask );

// Current device will point to the first available device
_camera_index = 0;
if( _device_list.size() > 0 )
_cv.notify_all();
// Current device will point to the first available device
_camera_index = 0;
if( _device_list.size() > 0 )
_cv.notify_all();
}
} );
}

/*static*/ std::shared_ptr< device_hub > device_hub::make( std::shared_ptr< librealsense::context > const & ctx,
int mask )
{
std::shared_ptr< device_hub > sptr( new device_hub( ctx, mask ) );
sptr->init( sptr );
return sptr;
}

device_hub::~device_hub()
{
}
Expand Down
6 changes: 5 additions & 1 deletion src/device_hub.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,12 @@ namespace librealsense
*/
class device_hub
{
device_hub( std::shared_ptr< context > ctx, int device_mask ); // private; use make()!
void init( std::shared_ptr< device_hub > const & );

public:
explicit device_hub(std::shared_ptr<librealsense::context> ctx, int mask = RS2_PRODUCT_LINE_ANY);
static std::shared_ptr< device_hub > make( std::shared_ptr< context > const &,
int device_mask = RS2_PRODUCT_LINE_ANY );

~device_hub();

Expand Down
8 changes: 4 additions & 4 deletions src/pipeline/pipeline.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ namespace librealsense
pipeline::pipeline(std::shared_ptr<librealsense::context> ctx) :
_ctx(ctx),
_dispatcher(10),
_hub(ctx, RS2_PRODUCT_LINE_ANY_INTEL),
_hub( device_hub::make( ctx, RS2_PRODUCT_LINE_ANY_INTEL )),
_synced_streams({ RS2_STREAM_COLOR, RS2_STREAM_DEPTH, RS2_STREAM_INFRARED, RS2_STREAM_FISHEYE })
{}

Expand Down Expand Up @@ -165,7 +165,7 @@ namespace librealsense
std::shared_ptr<device_interface> pipeline::wait_for_device(const std::chrono::milliseconds& timeout, const std::string& serial)
{
// pipeline's device selection shall be deterministic
return _hub.wait_for_device(timeout, false, serial);
return _hub->wait_for_device(timeout, false, serial);
}

std::shared_ptr<librealsense::context> pipeline::get_context() const
Expand Down Expand Up @@ -239,7 +239,7 @@ namespace librealsense
}

//hub returns true even if device already reconnected
if (!_hub.is_connected(*_active_profile->get_device()))
if (!_hub->is_connected(*_active_profile->get_device()))
{
try
{
Expand Down Expand Up @@ -300,7 +300,7 @@ namespace librealsense
}

//hub returns true even if device already reconnected
if (!_hub.is_connected(*_active_profile->get_device()))
if (!_hub->is_connected(*_active_profile->get_device()))
{
try
{
Expand Down
2 changes: 1 addition & 1 deletion src/pipeline/pipeline.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ namespace librealsense

mutable std::mutex _mtx;
std::shared_ptr<profile> _active_profile;
device_hub _hub;
std::shared_ptr< device_hub > _hub;
std::shared_ptr<config> _prev_conf;

private:
Expand Down
9 changes: 4 additions & 5 deletions src/rs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -188,16 +188,15 @@ rs2_context* rs2_create_context(int api_version, rs2_error** error) BEGIN_API_CA
verify_version_compatibility(api_version);

nlohmann::json settings;
return new rs2_context{ std::make_shared< librealsense::context >( settings ) };
return new rs2_context{ context::make( settings ) };
}
HANDLE_EXCEPTIONS_AND_RETURN(nullptr, api_version)

rs2_context* rs2_create_context_ex(int api_version, const char * json_settings, rs2_error** error) BEGIN_API_CALL
{
verify_version_compatibility(api_version);

return new rs2_context{
std::make_shared< librealsense::context >( json_settings ) };
return new rs2_context{ context::make( json_settings ) };
}
HANDLE_EXCEPTIONS_AND_RETURN(nullptr, api_version, json_settings)

Expand All @@ -210,7 +209,7 @@ NOEXCEPT_RETURN(, context)

rs2_device_hub* rs2_create_device_hub(const rs2_context* context, rs2_error** error) BEGIN_API_CALL
{
return new rs2_device_hub{ std::make_shared<librealsense::device_hub>(context->ctx) };
return new rs2_device_hub{ device_hub::make( context->ctx ) };
}
HANDLE_EXCEPTIONS_AND_RETURN(nullptr, context)

Expand Down Expand Up @@ -2652,7 +2651,7 @@ NOARGS_HANDLE_EXCEPTIONS_AND_RETURN(0)
rs2_device* rs2_create_software_device(rs2_error** error) BEGIN_API_CALL
{
// We're not given a context...
auto ctx = std::make_shared< context >( nlohmann::json::object( { { "dds", false } } ) );
auto ctx = context::make( nlohmann::json::object( { { "dds", false } } ) );
auto dev_info = std::make_shared< software_device_info >( ctx );
auto dev = std::make_shared< software_device >( dev_info );
dev_info->set_device( dev );
Expand Down
8 changes: 5 additions & 3 deletions src/rscore/device-factory.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,10 @@ class context;

class device_factory
{
protected:
context & _context;
std::weak_ptr< context > _context;

device_factory( context & ctx )
protected:
device_factory( std::shared_ptr< context > const & ctx )
: _context( ctx )
{
}
Expand All @@ -41,6 +41,8 @@ class device_factory

virtual ~device_factory() = default;

std::shared_ptr< context > get_context() const { return _context.lock(); }

// Query any subset of available devices and return them as device-info objects from which actual devices can be
// created as needed.
//
Expand Down
1 change: 1 addition & 0 deletions unit-tests/dds/test-librs-formats-conversion.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
# Copyright(c) 2023 Intel Corporation. All Rights Reserved.

#test:donotrun:!dds
#test:retries:gha 2

from rspy import log, test
import pyrealsense2 as rs
Expand Down

0 comments on commit cd2a5ec

Please sign in to comment.