@@ -50,102 +50,6 @@ NodeStatus SimpleActionNode::tick()
5050
5151// -------------------------------------------------------
5252
53- AsyncActionNode::AsyncActionNode (const std::string& name, const NodeConfiguration& config)
54- : ActionNodeBase(name, config)
55- {
56-
57- }
58-
59- AsyncActionNode::~AsyncActionNode ()
60- {
61- if (thread_.joinable ())
62- {
63- stopAndJoinThread ();
64- }
65- }
66-
67- void AsyncActionNode::waitStart ()
68- {
69- std::unique_lock<std::mutex> lock (start_mutex_);
70- while (!start_action_)
71- {
72- start_signal_.wait (lock);
73- }
74- start_action_ = false ;
75- }
76-
77- void AsyncActionNode::notifyStart ()
78- {
79- std::unique_lock<std::mutex> lock (start_mutex_);
80- start_action_ = true ;
81- start_signal_.notify_all ();
82- }
83-
84- void AsyncActionNode::asyncThreadLoop ()
85- {
86- while (keep_thread_alive_.load ())
87- {
88- waitStart ();
89-
90- // check keep_thread_alive_ again because the tick_engine_ could be
91- // notified from the method stopAndJoinThread
92- if (keep_thread_alive_)
93- {
94- // this will execute the blocking code.
95- try {
96- setStatus (tick ());
97- }
98- catch (std::exception&)
99- {
100- std::cerr << " \n Uncaught exception from the method tick() of an AsyncActionNode: ["
101- << registrationName () << " /" << name () << " ]\n " << std::endl;
102- exptr_ = std::current_exception ();
103- keep_thread_alive_ = false ;
104- }
105- }
106- }
107- }
108-
109- NodeStatus AsyncActionNode::executeTick ()
110- {
111- // send signal to other thread.
112- // The other thread is in charge for changing the status
113- if (status () == NodeStatus::IDLE)
114- {
115- if ( thread_.joinable () == false ) {
116- keep_thread_alive_ = true ;
117- thread_ = std::thread (&AsyncActionNode::asyncThreadLoop, this );
118- }
119- setStatus ( NodeStatus::RUNNING );
120- notifyStart ();
121- }
122-
123- if ( exptr_ )
124- {
125- std::rethrow_exception (exptr_);
126- }
127- return status ();
128- }
129-
130- void AsyncActionNode::stopAndJoinThread ()
131- {
132- keep_thread_alive_.store (false );
133- if ( status () == NodeStatus::RUNNING )
134- {
135- halt ();
136- }
137- else {
138- // loop in asyncThreadLoop() is blocked at waitStart(). Unblock it.
139- notifyStart ();
140- }
141-
142- if (thread_.joinable ())
143- {
144- thread_.join ();
145- }
146- }
147-
148-
14953SyncActionNode::SyncActionNode (const std::string &name, const NodeConfiguration& config):
15054 ActionNodeBase(name, config)
15155{}
@@ -260,3 +164,44 @@ void StatefulActionNode::halt()
260164 }
261165 setStatus (NodeStatus::IDLE);
262166}
167+
168+ NodeStatus BT::AsyncActionNode::executeTick ()
169+ {
170+ // send signal to other thread.
171+ // The other thread is in charge for changing the status
172+ if (status () == NodeStatus::IDLE)
173+ {
174+ setStatus ( NodeStatus::RUNNING );
175+ halt_requested_ = false ;
176+ thread_handle_ = std::async (std::launch::async, [this ]() {
177+
178+ try {
179+ setStatus (tick ());
180+ }
181+ catch (std::exception&)
182+ {
183+ std::cerr << " \n Uncaught exception from the method tick(): ["
184+ << registrationName () << " /" << name () << " ]\n " << std::endl;
185+ exptr_ = std::current_exception ();
186+ thread_handle_.wait ();
187+ }
188+ return status ();
189+ });
190+ }
191+
192+ if ( exptr_ )
193+ {
194+ std::rethrow_exception (exptr_);
195+ }
196+ return status ();
197+ }
198+
199+ void AsyncActionNode::halt ()
200+ {
201+ halt_requested_.store (true );
202+
203+ if ( thread_handle_.valid () ){
204+ thread_handle_.wait ();
205+ }
206+ thread_handle_ = {};
207+ }
0 commit comments