Skip to content

Commit

Permalink
try to remove deadlock
Browse files Browse the repository at this point in the history
  • Loading branch information
maloel committed Oct 11, 2023
1 parent 2dbaaf5 commit 8882934
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 29 deletions.
45 changes: 21 additions & 24 deletions src/device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -169,47 +169,44 @@ matcher_factory::create_timestamp_composite_matcher( std::vector< std::shared_pt
device::device(std::shared_ptr<context> ctx,
const platform::backend_device_group group,
bool device_changed_notifications)
: _context(ctx), _group(group), _is_valid(true),
_device_changed_notifications(device_changed_notifications),
_is_alive( std::make_shared< bool >( true ) )
: _context( ctx )
, _group( group )
, _device_changed_notifications( device_changed_notifications )
, _is_alive( std::make_shared< std::atomic< bool > >( true ) )
{
_profiles_tags = lazy<std::vector<tagged_profile>>([this]() { return get_profiles_tags(); });

if (_device_changed_notifications)
{
std::weak_ptr< bool > weak = _is_alive;
auto cb = new devices_changed_callback_internal([this, weak](rs2_device_list* removed, rs2_device_list* added)
{
// The callback can be called from one thread while the object is being destroyed by another.
// Check if members can still be accessed.
auto alive = weak.lock();
if( ! alive || ! *alive )
return;

// Update is_valid variable when device is invalid
std::lock_guard<std::mutex> lock(_device_changed_mtx);
for (auto& dev_info : removed->list)
std::weak_ptr< std::atomic< bool > > weak_alive = _is_alive;
auto cb = new devices_changed_callback_internal(
[weak_alive, group]( rs2_device_list * removed, rs2_device_list * added )
{
if (dev_info.info->get_device_data() == _group)
{
_is_valid = false;
// The callback can be called from one thread while the object is being destroyed by another.
// Check if members can still be accessed.
auto alive = weak_alive.lock();
if( ! alive || ! *alive )
return;

for( auto & dev_info : removed->list )
{
if( dev_info.info->get_device_data() == group )
{
*alive = false;
return;
}
}
}
});
} );

_callback_id = _context->register_internal_device_callback({ cb, [](rs2_devices_changed_callback* p) { p->release(); } });
}
}

device::~device()
{
*_is_alive = false;

if (_device_changed_notifications)
{
_context->unregister_internal_device_callback(_callback_id);
}

_sensors.clear();
}

Expand Down
8 changes: 3 additions & 5 deletions src/device.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,7 @@ class device : public virtual device_interface, public info_container

bool is_valid() const override
{
std::lock_guard<std::mutex> lock(_device_changed_mtx);
return _is_valid;
return *_is_alive;
}

void tag_profiles(stream_profiles profiles) const override;
Expand Down Expand Up @@ -104,12 +103,11 @@ class device : public virtual device_interface, public info_container
std::vector<std::shared_ptr<sensor_interface>> _sensors;
std::shared_ptr<context> _context;
const platform::backend_device_group _group;
bool _is_valid, _device_changed_notifications;
mutable std::mutex _device_changed_mtx;
bool _device_changed_notifications;
uint64_t _callback_id;
lazy<std::vector<tagged_profile>> _profiles_tags;

std::shared_ptr< bool > _is_alive; // Ensures object can be accessed
std::shared_ptr< std::atomic< bool > > _is_alive;
};

// Helper function that should be used when multiple FW calls needs to be made.
Expand Down

0 comments on commit 8882934

Please sign in to comment.