Skip to content

fix(LibCarla): port core bug fixes from ue4-dev#9585

Open
youtalk wants to merge 3 commits intocarla-simulator:ue5-devfrom
youtalk:fix/libcarla-core-bug-fixes
Open

fix(LibCarla): port core bug fixes from ue4-dev#9585
youtalk wants to merge 3 commits intocarla-simulator:ue5-devfrom
youtalk:fix/libcarla-core-bug-fixes

Conversation

@youtalk
Copy link

@youtalk youtalk commented Mar 12, 2026

Description

Port 5 core bug fixes from ue4-dev to ue5-dev:

  1. RPC server deadlock fix (ref: 0c477d6) — Add atomic shutdown flag and timeout loop in Server::WrapSyncCall to prevent deadlock on shutdown
  2. Vector3D assert removal (ref: 7b2ef1d) — Remove overly strict DEVELOPMENT_ASSERT in MakeUnitVector() that could crash on small vectors
  3. OpenDrive lane width (ref: 3b3b890) — Always create lane width attribute (including center lanes) to prevent missing width data
  4. yield() → sleep_for() (ref: 4c49a74) — Replace unreliable std::this_thread::yield() with sleep_for(100us) for proper CPU scheduling
  5. Assert relaxation (ref: 5161fb0) — Replace strict RELEASE_ASSERT in road Map with graceful skip logic

Note: Fixes 4 (GeoReferenceParser) and 5 (TrafficManager NaN) from the original plan were skipped — the ue5-dev codebase has completely different code in those areas.

Related #9583 (partial — PR #0a)

Where has this been tested?

  • Platform(s): Linux (Ubuntu 24.04)
  • Python version(s): 3.12
  • Unreal Engine version(s): 5.5

Possible Drawbacks

None expected. All fixes are well-understood ports from the stable ue4-dev branch. The assert relaxation changes error behavior from crash to skip, which is more forgiving but could mask issues in rare edge cases.


This change is Reviewable

- Fix RPC server deadlock with atomic shutdown flag (ref: 0c477d6)
- Remove overly strict assert in Vector3D::MakeUnitVector (ref: 7b2ef1d)
- Fix OpenDrive lane width for center lanes (ref: 3b3b890)
- Replace yield() with sleep_for(100us) (ref: 4c49a74)
- Relax RELEASE_ASSERT to graceful skip in road Map (ref: 5161fb0)
@update-docs
Copy link

update-docs bot commented Mar 12, 2026

Thanks for opening this pull request! The maintainers of this repository would appreciate it if you would update our CHANGELOG.md based on your changes.

@youtalk youtalk marked this pull request as ready for review March 12, 2026 05:12
@youtalk youtalk requested a review from a team as a code owner March 12, 2026 05:12
Copilot AI review requested due to automatic review settings March 12, 2026 05:12
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Ports a set of stability and correctness fixes from ue4-dev into ue5-dev, focusing on preventing shutdown deadlocks in the RPC server, reducing overly-strict asserts, and avoiding aggressive busy-wait behavior.

Changes:

  • Add a shutdown-aware wait loop for synchronous RPC calls to avoid deadlock during server shutdown.
  • Replace several std::this_thread::yield() busy-waits with sleep_for(100us) to improve scheduling behavior.
  • Relax/adjust validation behavior in geometry, OpenDrive lane parsing, and road waypoint generation to avoid hard crashes and missing data.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
Unreal/CarlaUnreal/Plugins/Carla/Source/Carla/Sensor/PixelReader.cpp Replaces yield() with sleep_for(100us) while polling GPU readback readiness.
Unreal/CarlaUnreal/Plugins/Carla/Source/Carla/Sensor/ImageUtil.cpp Replaces yield() with sleep_for(100us) in async readback polling; adds required headers.
LibCarla/source/carla/streaming/detail/tcp/ServerSession.cpp Replaces a synchronous-mode yield() loop with sleep_for(100us); adds <chrono>.
LibCarla/source/carla/rpc/Server.h Adds shutdown flag and timeout loop in sync RPC wrapper to avoid shutdown deadlock.
LibCarla/source/carla/road/Map.cpp Replaces strict RELEASE_ASSERT checks with skip/continue logic when successor/predecessor lane data is invalid.
LibCarla/source/carla/opendrive/parser/LaneParser.cpp Ensures a lane width entry is created even when <width> is absent (including center lane).
LibCarla/source/carla/geom/Vector3D.h Removes a strict development assert in MakeUnitVector().
LibCarla/source/carla/client/detail/Simulator.cpp Replaces yield() with sleep_for(100us) in frame-wait loop; adds <chrono>.
CHANGELOG.md Documents the set of ported bug fixes in LATEST changes.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +125 to +133
std::future_status status;
do {
status = result.wait_for(std::chrono::milliseconds(100));
} while (!shutdown_in_progress && (status != std::future_status::ready));
if (status==std::future_status::ready) {
return result.get();
} else {
return R();
}
Copy link

Copilot AI Mar 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When the server is shutting down and the posted sync task never runs, this wrapper returns a default-constructed R. For RPCs returning primitive types this can silently look like a valid result (e.g., 0), and for carla::rpc::Response<T> it will surface as an unhelpful "unknown error". Consider returning a deterministic shutdown-specific error (e.g., set a ResponseError message when R is a Response<...> / Response<void>, or throw an exception that rpclib can convert into an RPC error).

Copilot uses AI. Check for mistakes.
Comment on lines +125 to +133
std::future_status status;
do {
status = result.wait_for(std::chrono::milliseconds(100));
} while (!shutdown_in_progress && (status != std::future_status::ready));
if (status==std::future_status::ready) {
return result.get();
} else {
return R();
}
Copy link

Copilot AI Mar 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change introduces shutdown-aware waiting logic in WrapSyncCall, but there is no regression test covering the shutdown path (i.e., a client call blocked on SyncRunFor work that gets unblocked when Server::Stop() is called). Adding a unit/integration test in the existing test_rpc.cpp suite would help prevent deadlock regressions.

Copilot uses AI. Check for mistakes.
@@ -66,7 +66,6 @@ namespace geom {

inline Vector3D MakeUnitVector() const {
const float length = Length();
Copy link

Copilot AI Mar 12, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With the DEVELOPMENT_ASSERT removed, MakeUnitVector() now always divides by length without any guard. For zero-length vectors this will produce inf/NaN components (and for very small lengths it can amplify numerical noise). Consider either restoring a weaker guard (only for length == 0 / very small) or routing callers toward MakeSafeUnitVector() for potentially-degenerate inputs.

Suggested change
const float length = Length();
const float length = Length();
if (length <= 0.0f) {
// Avoid division by zero for zero-length vectors; return the original vector.
return *this;
}

Copilot uses AI. Check for mistakes.
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
@jorge-kabuto jorge-kabuto self-assigned this Mar 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants