Running and Stopping
🚧 Documentation is under development
The Holoscan SDK guide is currently under active development. Some sections may be incomplete or change without notice.
Questions? Contact RidgeRun or email to support@ridgerun.com.
-
Overview
-
Build, Run, and Validate
-
Core Concepts
-
Operators and Graphs
-
Tensor Data and Memory
-
Interprocess Communication
-
-
Application and Operator Development
- Building an HSDK Application
- Writing a Minimal Operator
- Typed Parameters and Configuration
- Reading, Writing, and Forwarding Data
- Writing Tensor Operators
- Complete Operator Patterns
- Authoring Runtime Behavior
- Runtime Parameter Updates
- Lifecycle Callbacks and Restart Control
- Performance and Debugging
- SDK Source Map
-
Operator Reference
-
Core Operators
-
Holoscan Camera
-
Holoscan RidgeRun
- Overview
- Build and Installation
- ArgusCameraOp
- V4L2SourceOp
- V4L2UserPtrSourceOp
- BgraToPlanarTensorOp
- RawBayerToBgraOp
- RawBayerToYoloTensorOp
- YuyvToBgraOp
- TensorRtInferenceOp
- DrmDisplayOp
- DrmBgraDisplayOp
- X11DisplayOp
- CudaCompositorOp
- DepthColorizerOp
- FakesinkOp
- FrameSkipperOp
- InterprocessSrcOp
- TestPatternOp
-
-
Migration from Holoscan 4.x
-
Examples
-
Core
-
Holoscan Camera
-
Holoscan RidgeRun
-
-
Benchmark and Use Cases
-
Holoscan vs GStreamer
- Overview
-
Capture and Display
-
Capture and Inference
- Compare the workloads
- Implemented Applications
- Framework Selection
- Interprocess
-
Running and Stopping
After a graph has been compiled into an accepted ExecutionPlan, the application chooses how to start it and how to decide that the work is complete. A command-line tool often uses blocking execution. An application that also manages a user interface, device control, or another service usually keeps the run in an asynchronous session.
Both choices use the same order: start the accepted plan, observe the application, request a cooperative stop when appropriate, wait for cleanup, and inspect the terminal result.
Start with the execution choice
For a simple application whose main work is the graph, use the blocking holoscan::run() function:
// plan is an accepted holoscan::ExecutionPlan. return holoscan::run(plan);
The call keeps the current thread in the run until the graph reaches a terminal state. A zero return value represents natural or explicitly requested successful completion. A stopped or failed run returns nonzero.
When the surrounding application must continue doing other work, use holoscan::run_async(). It returns a move-only RunSession that owns the runtime work:
auto session = holoscan::run_async(plan); // The application can do other work while the graph runs.
Keep the session owner alive while the graph is active. Moving the session transfers the stop and wait authority to the new owner.
Use cooperative stop and wait
The RunSession::request_stop() function asks the graph to stop without waiting. The RunSession::wait() function joins the run and cleanup. Together they give the application a clear shutdown point:
#include <chrono>
#include <thread>
int run_for(const holoscan::ExecutionPlan& plan,
std::chrono::milliseconds duration) {
auto session = holoscan::run_async(plan);
std::this_thread::sleep_for(duration);
session.request_stop();
session.wait();
const auto outcome = session.termination();
return outcome == holoscan::RunTermination::kFailed ? 1 : 0;
}
The example uses a timer to keep the control path small. A real application can request the same stop when its own shutdown event arrives. Stop is cooperative: callbacks that are already running must return, and a nonterminating CUDA kernel or callback can keep wait() blocked.
Read the terminal outcome
The RunTermination enum summarizes the session after cleanup:
| Outcome | Meaning |
|---|---|
kCompleted
|
Finite execution and mandatory cleanup completed successfully. |
kRequestedCompleted
|
An operator requested whole-run success and cleanup completed successfully. |
kStopped
|
The application requested a cooperative stop and cleanup completed successfully. |
kFailed
|
Startup, execution, or mandatory cleanup failed. |
kRunning
|
Work is still active. It is not a terminal result. |
Inspect session.termination() after wait(). A clean stop is expected when the application reached its own stopping condition. Treat kFailed as an error and read the retained diagnostics before returning.
An operator can request whole-run success through ExecutionContext::request_completion() from its active compute callback. That produces kRequestedCompleted. It does not promise end-of-stream propagation or delivery of queued samples, so use it only when ending the complete run at that boundary is acceptable.
Choose who owns process signals
Plain run_async(plan) leaves signal handling to the application. Blocking run(plan) uses the SDK's managed signal policy on Linux. If another framework already owns SIGINT or SIGTERM, call run(plan, RunSignalPolicy::kCallerManaged) and keep signal ownership in that framework.
For asynchronous execution with SDK-managed signals, create ManagedShutdownSignals::create() on the initial application thread before starting participant threads. Pass the open domain to run_async(plan, signals), keep it alive until the session has stopped, and close it on its creator thread.
A managed signal requests the same cooperative stop described above. It does not force a callback or kernel to finish. Managed signal admission is a Linux process concern, so keep it after the basic run path unless the application embeds another signal owner.
Read diagnostics after cleanup
When a run fails, inspect session.diagnostics() after wait(). The records identify the observed failure stage and provide structured fields for program decisions. Use the configured diagnostic formatter for human-readable output, but do not branch on log prose.
Separate the stage that failed:
| Observation | First place to investigate |
|---|---|
| The application does not configure or compile. | The SDK installation, CMake prefix, compiler, and example source. |
compile(graph) rejects the graph.
|
The graph connections, operator contracts, payload types, and plan diagnostics. |
| The plan is accepted but the session fails before callbacks run. | Runtime bindings, device availability, model files, and package components. |
| A callback runs and then the session fails. | The operator result, data access, device operation, and retained diagnostics. |