Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix crash with desynced frames; add unit-test #9715

Merged
merged 13 commits into from
Sep 5, 2021
54 changes: 32 additions & 22 deletions common/utilities/string/windows.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,28 +12,38 @@ namespace utilities {
namespace string {
namespace windows {

inline std::string win_to_utf(const WCHAR * s)
{
auto len = WideCharToMultiByte(CP_UTF8, 0, s, -1, nullptr, 0, nullptr, nullptr);
std::ostringstream ss;

if (len == 0)
{
ss << "WideCharToMultiByte(...) returned 0 and GetLastError() is " << GetLastError();
throw std::runtime_error(ss.str());
}

std::string buffer(len - 1, ' ');
len = WideCharToMultiByte(CP_UTF8, 0, s, -1, &buffer[0], static_cast<int>(buffer.size()) + 1, nullptr, nullptr);
if (len == 0)
{
ss.clear();
ss << "WideCharToMultiByte(...) returned 0 and GetLastError() is " << GetLastError();
throw std::runtime_error(ss.str());
}

return buffer;
}

inline std::string win_to_utf( const WCHAR * s, size_t wlen = -1 )
{
auto len = WideCharToMultiByte( CP_UTF8, 0, s, (int)wlen, nullptr, 0, nullptr, nullptr );
if( len == 0 )
{
std::ostringstream ss;
ss << "WideCharToMultiByte(...) returned 0 and GetLastError() is " << GetLastError();
throw std::runtime_error( ss.str() );
}

std::string buffer;
buffer.reserve( len );
len = WideCharToMultiByte( CP_UTF8, 0, s, (int)wlen, &buffer[0], len, nullptr, nullptr );
if( len == 0 )
{
std::ostringstream ss;
ss << "WideCharToMultiByte(...) returned 0 and GetLastError() is " << GetLastError();
throw std::runtime_error( ss.str() );
}
buffer.resize( len );

return buffer;
}


inline std::string win_to_utf( std::wstring const & s )
{
return win_to_utf( s.c_str(), s.length() );
}


} // namespace windows
} // namespace string
} // namespace utilities
Expand Down
1 change: 1 addition & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ target_sources(${LRS_TARGET}
"${CMAKE_CURRENT_LIST_DIR}/serialized-utilities.cpp"
"${CMAKE_CURRENT_LIST_DIR}/frame.cpp"
"${CMAKE_CURRENT_LIST_DIR}/points.cpp"
"${CMAKE_CURRENT_LIST_DIR}/to-string.cpp"

"${CMAKE_CURRENT_LIST_DIR}/algo.h"
"${CMAKE_CURRENT_LIST_DIR}/api.h"
Expand Down
3 changes: 2 additions & 1 deletion src/concurrency.h
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,7 @@ class single_consumer_queue
bool empty() const { return ! size(); }
};

// A single_consumer_queue meant to hold frame_holder objects
template<class T>
class single_consumer_frame_queue
{
Expand All @@ -207,7 +208,7 @@ class single_consumer_frame_queue

bool enqueue( T && item )
{
if( item.is_blocking() )
maloel marked this conversation as resolved.
Show resolved Hide resolved
if( item->is_blocking() )
return _queue.blocking_enqueue( std::move( item ) );
else
return _queue.enqueue( std::move( item ) );
Expand Down
45 changes: 23 additions & 22 deletions src/frame.h
Original file line number Diff line number Diff line change
Expand Up @@ -147,38 +147,39 @@ class frame_interface : public sensor_part

struct LRS_EXTENSION_API frame_holder
{
frame_interface * frame;
frame_interface * frame = nullptr;

frame_interface * operator->() const { return frame; }
frame_holder() = default;
frame_holder( const frame_holder & other ) = delete;
frame_holder( frame_holder && other ) { std::swap( frame, other.frame ); }
// non-acquiring ctor: will assume the frame has already been acquired!
frame_holder( frame_interface * const f ) { frame = f; }
frame_holder::~frame_holder() { reset(); }

operator bool() const { return frame != nullptr; }
// return a new holder after acquiring the frame
frame_holder frame_holder::clone() const { return acquire( frame ); }
static frame_holder acquire( frame_interface * const f ) { if( f ) f->acquire(); return frame_holder( f ); }

operator frame_interface *() const { return frame; }
frame_interface * operator->() const { return frame; }
operator bool() const { return frame != nullptr; }

frame_holder( frame_interface * f ) { frame = f; }

~frame_holder();

frame_holder( frame_holder && other )
: frame( other.frame )
frame_holder & operator=( const frame_holder & other ) = delete;
frame_holder & operator=( frame_holder && other )
{
other.frame = nullptr;
reset();
std::swap( frame, other.frame );
return *this;
}

frame_holder()
: frame( nullptr )
void reset()
{
if( frame )
{
frame->release();
frame = nullptr;
}
}

frame_holder & operator=( frame_holder && other );

frame_holder clone() const;

bool is_blocking() const { return frame->is_blocking(); };

private:
frame_holder & operator=( const frame_holder & other ) = delete;
frame_holder( const frame_holder & other );
};


Expand Down
2 changes: 1 addition & 1 deletion src/proc/synthetic-stream.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -469,7 +469,7 @@ namespace librealsense

for (auto&& f : holders)
{
if (f.is_blocking())
if (f->is_blocking())
res->set_blocking(true);
}

Expand Down
26 changes: 0 additions & 26 deletions src/rs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1263,32 +1263,6 @@ const char* rs2_get_failed_args(const rs2_error* error) { return error ? error->
const char* rs2_get_error_message(const rs2_error* error) { return error ? error->message.c_str() : nullptr; }
rs2_exception_type rs2_get_librealsense_exception_type(const rs2_error* error) { return error ? error->exception_type : RS2_EXCEPTION_TYPE_UNKNOWN; }

const char* rs2_stream_to_string(rs2_stream stream) { return librealsense::get_string(stream); }
const char* rs2_format_to_string(rs2_format format) { return librealsense::get_string(format); }
const char* rs2_distortion_to_string(rs2_distortion distortion) { return librealsense::get_string(distortion); }
const char* rs2_option_to_string(rs2_option option) { return librealsense::get_string(option); }
const char* rs2_camera_info_to_string(rs2_camera_info info) { return librealsense::get_string(info); }
const char* rs2_timestamp_domain_to_string(rs2_timestamp_domain info) { return librealsense::get_string(info); }
const char* rs2_notification_category_to_string(rs2_notification_category category) { return librealsense::get_string(category); }
const char* rs2_calib_target_type_to_string(rs2_calib_target_type type) { return librealsense::get_string(type); }
const char* rs2_sr300_visual_preset_to_string(rs2_sr300_visual_preset preset) { return librealsense::get_string(preset); }
const char* rs2_log_severity_to_string(rs2_log_severity severity) { return librealsense::get_string(severity); }
const char* rs2_exception_type_to_string(rs2_exception_type type) { return librealsense::get_string(type); }
const char* rs2_playback_status_to_string(rs2_playback_status status) { return librealsense::get_string(status); }
const char* rs2_extension_type_to_string(rs2_extension type) { return librealsense::get_string(type); }
const char* rs2_matchers_to_string(rs2_matchers matcher) { return librealsense::get_string(matcher); }
const char* rs2_frame_metadata_to_string(rs2_frame_metadata_value metadata) { return librealsense::get_string(metadata); }
const char* rs2_extension_to_string(rs2_extension type) { return rs2_extension_type_to_string(type); }
const char* rs2_frame_metadata_value_to_string(rs2_frame_metadata_value metadata) { return rs2_frame_metadata_to_string(metadata); }
const char* rs2_l500_visual_preset_to_string(rs2_l500_visual_preset preset) { return get_string(preset); }
const char* rs2_sensor_mode_to_string(rs2_sensor_mode mode) { return get_string(mode); }
const char* rs2_ambient_light_to_string( rs2_ambient_light ambient ) { return get_string(ambient); }
const char* rs2_digital_gain_to_string(rs2_digital_gain gain) { return get_string(gain); }
const char* rs2_cah_trigger_to_string( int mode ) { return "DEPRECATED as of 2.46"; }
const char* rs2_calibration_type_to_string(rs2_calibration_type type) { return get_string(type); }
const char* rs2_calibration_status_to_string(rs2_calibration_status status) { return get_string(status); }
const char* rs2_host_perf_mode_to_string(rs2_host_perf_mode mode) { return get_string(mode); }

void rs2_log_to_console(rs2_log_severity min_severity, rs2_error** error) BEGIN_API_CALL
{
librealsense::log_to_console(min_severity);
Expand Down
Loading