SMACC2
Loading...
Searching...
No Matches
smacc_client_async_behavior.cpp
Go to the documentation of this file.
1// Copyright 2025 Robosoft Inc.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15/*****************************************************************************************************************
16 *
17 * Authors: Pablo Inigo Blasco, Brett Aldrich
18 *
19 ******************************************************************************************************************/
20
22
23using namespace std::chrono_literals;
24
25namespace smacc2
26{
28{
29 RCLCPP_INFO_STREAM(getLogger(), "[" << getName() << "] asynchronous onEntry thread started");
30 this->onEntryThread_ = std::async(
31 std::launch::async,
32 [=]
33 {
34 this->onEntry();
35 this->postFinishEventFn_();
36 RCLCPP_INFO_STREAM(getLogger(), "[" << getName() << "] asynchronous onEntry thread finished");
37 return 0;
38 });
39}
40
42 std::optional<std::future<int>> & threadfut, bool requestFinish)
43{
44 try
45 {
46 rclcpp::Rate r(100);
47 while (rclcpp::ok())
48 {
49 if (threadfut && threadfut->valid())
50 {
51 auto status = threadfut->wait_for(std::chrono::milliseconds(20));
52 if (status == std::future_status::ready)
53 {
54 // done
55 threadfut->get();
56 break;
57 }
58 else
59 {
60 // in progress
61 RCLCPP_INFO_STREAM(
62 getLogger(),
63 "[" << getName()
64 << "] fut valid but waiting for asynchronous onEntry thread to finish: state: "
65 << (int)status);
66 }
67 }
68 else
69 {
70 RCLCPP_INFO_STREAM(
71 getLogger(),
72 "[" << getName()
73 << "] waiting future onEntryThread. It was not even created. Skipping wait.");
74 break;
75 }
76 rclcpp::sleep_for(100ms);
77 RCLCPP_WARN_THROTTLE(
78 getLogger(), *(getNode()->get_clock()), 1000,
79 "[%s] waiting for finishing client behavior, before leaving the state. Is the client "
80 "behavior stuck? requesting force finish",
81 this->getName().c_str());
82
83 if (requestFinish) requestForceFinish();
84 }
85 }
86 catch (const std::exception & e)
87 {
88 RCLCPP_DEBUG(
89 getLogger(),
90 "[SmaccAsyncClientBehavior] trying to join function, but it was already finished.");
91 }
92}
93
95{
96 waitFutureIfNotFinished(this->onEntryThread_, requestFinish);
97}
98
100{
101 RCLCPP_INFO_STREAM(getLogger(), "[" << getName() << "] onExit - join async onEntry thread");
102 this->waitOnEntryThread(true);
103
104 RCLCPP_INFO_STREAM(
105 getLogger(), "[" << getName() << "] onExit - Creating asynchronous onExit thread");
106 this->onExitThread_ = std::async(
107 std::launch::async,
108 [=]
109 {
110 this->onExit();
111 RCLCPP_INFO_STREAM(getLogger(), "[" << getName() << "] asynchronous onExit done.");
112 return 0;
113 });
114}
115
117{
118 RCLCPP_DEBUG_STREAM(
119 getLogger(), "[" << getName()
120 << "] Destroying client behavior- Waiting finishing of asynchronous onExit "
121 "thread");
122 try
123 {
124 if (this->onExitThread_)
125 {
126 this->onExitThread_->get();
127 }
128 }
129 catch (...)
130 {
131 RCLCPP_DEBUG(
132 getLogger(),
133 "[SmaccAsyncClientBehavior] trying to Join onExit function, but it was already "
134 "finished.");
135 }
136
137 RCLCPP_DEBUG_STREAM(
138 getLogger(), "[" << getName()
139 << "] Destroying client behavior- onExit thread finished. Proccedding "
140 "destruction.");
141}
142
144
146
148
150{
151 RCLCPP_FATAL_STREAM_THROTTLE(
152 getLogger(), *(getNode()->get_clock()), 1000,
153 "[" << getName() << "] " << ((uint64_t)this) << " requestForceFinish");
155}
156
158{
159 std::string shut = "";
161 {
162 shut = "True";
163 }
164 else
165 {
166 shut = "False";
167 }
169}
170
171} // namespace smacc2
virtual rclcpp::Logger getLogger() const
virtual rclcpp::Node::SharedPtr getNode() const
bool isShutdownRequested()
onEntry is executed in a new thread. However the current state cannot be left until the onEntry threa...
std::optional< std::future< int > > onExitThread_
std::optional< std::future< int > > onEntryThread_
void waitFutureIfNotFinished(std::optional< std::future< int > > &threadfut, bool requestFinish)