Skip to content

Commit c14bf3c

Browse files
committed
Add CPP DeadlineMonitoring API
1 parent 3f8531d commit c14bf3c

11 files changed

Lines changed: 706 additions & 4 deletions

File tree

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,8 @@ You can also use the config `--config=x86_64-linux` to build for linux.
6363
## IDE support
6464

6565
### C++
66-
Use visual studio code with `clangd`. Make sure You don't have installed MS C++ Intellisense as this is likely to clash with `clangd`.
67-
Then you need to call `./scripts/generate_cpp_compile_commands.sh` to generate compilation DB for clangd and restart it in Vscode. Indexing shall work.
66+
Use Visual Studio Code with `clangd`. Make sure you don't have the MS C++ IntelliSense extension installed as this is likely to clash with `clangd`.
67+
Then you need to call `./scripts/generate_cpp_compile_commands.sh` to generate compilation DB for clangd and restart it in VS Code. Indexing shall work.
6868

6969
### Rust
7070

src/health_monitoring_lib/BUILD

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@
1111
# SPDX-License-Identifier: Apache-2.0
1212
# *******************************************************************************
1313

14-
load("@rules_rust//rust:defs.bzl", "rust_library", "rust_test")
14+
load("@rules_rust//rust:defs.bzl", "rust_library", "rust_test", "rust_static_library")
15+
load("@score_baselibs//:bazel/unit_tests.bzl", "cc_gtest_unit_test", "cc_unit_test_suites_for_host_and_qnx")
1516

1617
rust_library(
1718
name = "health_monitoring_lib",
@@ -26,10 +27,59 @@ rust_library(
2627
],
2728
)
2829

30+
31+
rust_static_library(
32+
name = "health_monitoring_lib_ffi",
33+
srcs = glob(["src/**/*.rs"]),
34+
crate_name = "health_monitoring_lib",
35+
proc_macro_deps = [
36+
"@score_baselibs_rust//src/testing_macros:score_testing_macros",
37+
],
38+
visibility = ["//visibility:public"],
39+
deps = [
40+
"@score_baselibs_rust//src/log/score_log",
41+
],
42+
)
43+
2944
rust_test(
3045
name = "tests",
3146
crate = ":health_monitoring_lib",
3247
deps = [
3348
"@score_baselibs_rust//src/log/stdout_logger",
3449
],
3550
)
51+
52+
cc_library(
53+
name = "health_monitoring_lib_cc",
54+
srcs = [
55+
"cpp/deadline/deadline_monitor.cpp",
56+
"cpp/health_monitor.cpp",
57+
"cpp/common.cpp",
58+
"cpp/ffi_helpers.h",
59+
],
60+
hdrs = [
61+
"cpp/include/score/hm/deadline/deadline_monitor.h",
62+
"cpp/include/score/hm/common.h",
63+
"cpp/include/score/hm/health_monitor.h"
64+
65+
],
66+
visibility = ["//visibility:public"],
67+
strip_include_prefix = "cpp/include",
68+
deps = [
69+
":health_monitoring_lib_ffi",
70+
"@score_baselibs//score/result",
71+
],
72+
copts = [
73+
"-Isrc/health_monitoring_lib/cpp", # private include path
74+
],
75+
)
76+
77+
cc_gtest_unit_test(
78+
name = "cpp_tests",
79+
srcs = [
80+
"cpp/tests/health_monitor_test.cpp",
81+
],
82+
deps = [
83+
":health_monitoring_lib_cc",
84+
],
85+
)
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
#include <score/hm/common.h>
2+
3+
namespace score::hm::internal
4+
{
5+
6+
DroppableFFIHandle::DroppableFFIHandle(FFIHandle handle, DropFn drop_fn) : handle_(handle), drop_fn_(drop_fn) {}
7+
8+
DroppableFFIHandle::DroppableFFIHandle(DroppableFFIHandle&& other) noexcept
9+
: handle_(other.handle_), drop_fn_(other.drop_fn_)
10+
{
11+
other.handle_ = nullptr;
12+
other.drop_fn_ = nullptr;
13+
}
14+
15+
DroppableFFIHandle& DroppableFFIHandle::operator=(DroppableFFIHandle&& other) noexcept
16+
{
17+
if (this != &other)
18+
{
19+
// Clean up existing resources
20+
if (drop_fn_)
21+
{
22+
drop_fn_(handle_);
23+
}
24+
25+
// Move resources from other
26+
handle_ = other.handle_;
27+
drop_fn_ = other.drop_fn_;
28+
29+
// Nullify other's resources
30+
other.handle_ = nullptr;
31+
other.drop_fn_ = nullptr;
32+
}
33+
return *this;
34+
}
35+
36+
::score::cpp::optional<FFIHandle> DroppableFFIHandle::as_rust_handle() const
37+
{
38+
if (handle_ == nullptr)
39+
{
40+
return ::score::cpp::nullopt;
41+
}
42+
43+
return handle_;
44+
}
45+
46+
::score::cpp::optional<FFIHandle> DroppableFFIHandle::drop_by_rust()
47+
{
48+
if (handle_ == nullptr)
49+
{
50+
return ::score::cpp::nullopt;
51+
}
52+
53+
FFIHandle temp = handle_;
54+
handle_ = nullptr;
55+
drop_fn_ = nullptr;
56+
57+
return temp;
58+
}
59+
60+
DroppableFFIHandle::~DroppableFFIHandle()
61+
{
62+
// Clean up resources associated with the FFI handle
63+
if (drop_fn_)
64+
{
65+
drop_fn_(handle_);
66+
}
67+
}
68+
69+
} // namespace score::hm::internal
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
#include "score/hm/deadline/deadline_monitor.h"
2+
#include "ffi_helpers.h"
3+
4+
extern "C" {
5+
using namespace score::hm;
6+
using namespace score::hm::internal;
7+
using namespace score::hm::deadline;
8+
9+
internal::FFIHandle deadline_monitor_builder_create();
10+
void deadline_monitor_builder_destroy(internal::FFIHandle handle);
11+
void deadline_monitor_builder_add_deadline(internal::FFIHandle handler,
12+
const IdentTag* tag,
13+
uint32_t min,
14+
uint32_t max);
15+
int deadline_monitor_cpp_get_deadline(FFIHandle handler, const IdentTag* tag, FFIHandle* out);
16+
void deadline_monitor_cpp_destroy(FFIHandle handler);
17+
void deadline_destroy(FFIHandle deadline_handle);
18+
int deadline_start(FFIHandle deadline_handle);
19+
void deadline_stop(FFIHandle deadline_handle);
20+
}
21+
22+
namespace score::hm::deadline
23+
{
24+
DeadlineMonitorBuilder::DeadlineMonitorBuilder()
25+
: monitor_builder_handler_(deadline_monitor_builder_create(), &deadline_monitor_builder_destroy)
26+
{
27+
}
28+
29+
DeadlineMonitorBuilder DeadlineMonitorBuilder::add_deadline(const IdentTag& tag, const TimeRange& range) &&
30+
{
31+
auto handle = monitor_builder_handler_.as_rust_handle();
32+
SCORE_LANGUAGE_FUTURECPP_PRECONDITION(handle.has_value());
33+
34+
deadline_monitor_builder_add_deadline(handle.value(), &tag, range.min_as_u32(), range.max_as_u32());
35+
36+
return std::move(*this);
37+
}
38+
39+
DeadlineMonitor::DeadlineMonitor(FFIHandle handle) : monitor_handle_(handle, &deadline_monitor_cpp_destroy) {}
40+
41+
score::cpp::expected<Deadline, score::hm::Error> DeadlineMonitor::get_deadline(const IdentTag& tag)
42+
{
43+
auto handle = monitor_handle_.as_rust_handle();
44+
SCORE_LANGUAGE_FUTURECPP_PRECONDITION(handle.has_value());
45+
46+
internal::FFIHandle ret = nullptr;
47+
auto result = deadline_monitor_cpp_get_deadline(handle.value(), &tag, &ret);
48+
49+
if (result != kSuccess)
50+
{
51+
return score::cpp::unexpected(::score::hm::ffi::fromRustError(result));
52+
}
53+
54+
return score::cpp::expected<Deadline, score::hm::Error>(Deadline{ret});
55+
}
56+
57+
Deadline::Deadline(internal::FFIHandle handle) : deadline_handle_(handle, &deadline_destroy), has_handle_(false) {}
58+
59+
Deadline::~Deadline()
60+
{
61+
SCORE_LANGUAGE_FUTURECPP_PRECONDITION(!has_handle_);
62+
}
63+
64+
score::cpp::expected<DeadlineHandle, score::hm::Error> Deadline::start()
65+
{
66+
if (has_handle_)
67+
{
68+
return score::cpp::unexpected(::score::hm::Error::WrongState);
69+
}
70+
71+
auto handle = deadline_handle_.as_rust_handle();
72+
SCORE_LANGUAGE_FUTURECPP_PRECONDITION(handle.has_value());
73+
74+
auto result = deadline_start(handle.value());
75+
if (result != kSuccess)
76+
{
77+
return score::cpp::unexpected(::score::hm::ffi::fromRustError(result));
78+
}
79+
80+
has_handle_ = true;
81+
return score::cpp::expected<DeadlineHandle, score::hm::Error>(DeadlineHandle{*this});
82+
}
83+
84+
DeadlineHandle::DeadlineHandle(Deadline& deadline) : was_stopped_(false), deadline_(deadline) {}
85+
86+
void DeadlineHandle::stop()
87+
{
88+
SCORE_LANGUAGE_FUTURECPP_PRECONDITION(deadline_.has_value());
89+
90+
if (!was_stopped_)
91+
{
92+
was_stopped_ = true;
93+
auto handle = deadline_.value().get().deadline_handle_.as_rust_handle();
94+
SCORE_LANGUAGE_FUTURECPP_PRECONDITION(handle.has_value());
95+
96+
deadline_stop(handle.value());
97+
}
98+
}
99+
100+
DeadlineHandle::DeadlineHandle(DeadlineHandle&& other)
101+
: was_stopped_(other.was_stopped_), deadline_(std::move(other.deadline_))
102+
{
103+
other.was_stopped_ = true;
104+
other.deadline_ = ::score::cpp::optional<std::reference_wrapper<Deadline>>{}; // None
105+
}
106+
107+
DeadlineHandle::~DeadlineHandle()
108+
{
109+
if (!deadline_.has_value())
110+
{
111+
return;
112+
}
113+
114+
stop();
115+
deadline_.value().get().has_handle_ = false;
116+
}
117+
118+
} // namespace score::hm::deadline
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
#ifndef SCORE_HM_FFI_HELPERS_HPP
2+
#define SCORE_HM_FFI_HELPERS_HPP
3+
4+
namespace score::hm::ffi
5+
{
6+
7+
inline Error fromRustError(int ffi_error_code)
8+
{
9+
switch (ffi_error_code)
10+
{
11+
case 1:
12+
return Error::NotFound;
13+
case 2:
14+
return Error::AlreadyExists;
15+
case 3:
16+
return Error::InvalidArgument;
17+
case 4:
18+
return Error::WrongState;
19+
case 5:
20+
return Error::Failed;
21+
default:
22+
assert(false && "Unknown FFI error code");
23+
return Error::InvalidArgument; // Fallback
24+
}
25+
}
26+
27+
} // namespace score::hm::ffi
28+
29+
#endif // SCORE_HM_FFI_HELPERS_HPP
Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
#include "score/hm/health_monitor.h"
2+
3+
extern "C" {
4+
using namespace score::hm;
5+
6+
internal::FFIHandle health_monitor_builder_create();
7+
void health_monitor_builder_destroy(internal::FFIHandle handler);
8+
9+
internal::FFIHandle health_monitor_builder_build(internal::FFIHandle health_monitor_builder_handle);
10+
void health_monitor_builder_add_deadline_monitor(internal::FFIHandle handle,
11+
const IdentTag* tag,
12+
internal::FFIHandle monitor_handle);
13+
14+
internal::FFIHandle health_monitor_get_deadline_monitor(internal::FFIHandle health_monitor_handle, const IdentTag* tag);
15+
16+
void health_monitor_destroy(internal::FFIHandle handler);
17+
}
18+
19+
namespace score::hm
20+
{
21+
22+
HealthMonitorBuilder::HealthMonitorBuilder()
23+
: health_monitor_builder_handle_{health_monitor_builder_create(), &health_monitor_builder_destroy}
24+
{
25+
}
26+
27+
HealthMonitorBuilder HealthMonitorBuilder::add_deadline_monitor(const IdentTag& tag,
28+
deadline::DeadlineMonitorBuilder&& monitor) &&
29+
{
30+
auto monitor_handle = monitor.drop_by_rust();
31+
SCORE_LANGUAGE_FUTURECPP_PRECONDITION(monitor_handle.has_value());
32+
SCORE_LANGUAGE_FUTURECPP_PRECONDITION(health_monitor_builder_handle_.as_rust_handle().has_value());
33+
34+
health_monitor_builder_add_deadline_monitor(
35+
health_monitor_builder_handle_.as_rust_handle().value(), &tag, monitor_handle.value());
36+
return std::move(*this);
37+
}
38+
39+
HealthMonitor HealthMonitorBuilder::build() &&
40+
{
41+
auto handle = health_monitor_builder_handle_.drop_by_rust();
42+
SCORE_LANGUAGE_FUTURECPP_PRECONDITION(handle.has_value());
43+
44+
return HealthMonitor(health_monitor_builder_build(handle.value()));
45+
}
46+
47+
HealthMonitor::HealthMonitor(internal::FFIHandle handle) : health_monitor_(handle)
48+
{
49+
// Initialize health monitor
50+
}
51+
52+
score::cpp::expected<deadline::DeadlineMonitor, Error> HealthMonitor::get_deadline_monitor(const IdentTag& tag)
53+
{
54+
auto maybe_monitor = health_monitor_get_deadline_monitor(health_monitor_, &tag);
55+
56+
if (maybe_monitor != nullptr)
57+
{
58+
59+
return score::cpp::expected<deadline::DeadlineMonitor, Error>(deadline::DeadlineMonitor{maybe_monitor});
60+
}
61+
62+
return score::cpp::unexpected(Error::NotFound);
63+
}
64+
65+
HealthMonitor::~HealthMonitor()
66+
{
67+
if (health_monitor_ != nullptr)
68+
{
69+
health_monitor_destroy(health_monitor_);
70+
}
71+
}
72+
73+
HealthMonitor& HealthMonitor::operator=(HealthMonitor&& other)
74+
{
75+
if (this != &other)
76+
{
77+
if (health_monitor_ != nullptr)
78+
{
79+
health_monitor_destroy(health_monitor_);
80+
}
81+
health_monitor_ = std::move(other.health_monitor_);
82+
other.health_monitor_ = nullptr;
83+
}
84+
return *this;
85+
}
86+
87+
} // namespace score::hm

0 commit comments

Comments
 (0)