32 nassertv(_waiting.empty());
44 if (set_future_state(FS_cancelled)) {
58 output(std::ostream &out)
const {
63 case FS_locked_pending:
70 out <<
" (cancelled)";
73 out <<
" (**INVALID**)";
87 PStatTimer timer(AsyncTaskChain::_wait_pcollector);
88 if (task_cat.is_debug()) {
90 <<
"Waiting for future " << *
this <<
"\n";
110 PStatTimer timer(AsyncTaskChain::_wait_pcollector);
111 if (task_cat.is_debug()) {
113 <<
"Waiting up to " << timeout <<
" seconds for future " << *
this <<
"\n";
138 Futures::iterator it;
139 for (it = _waiting.begin(); it != _waiting.end(); ++it) {
141 if (fut->is_task()) {
149 if (
gather->set_future_state(FS_finished)) {
159 if (clean_exit && !_done_event.empty()) {
160 PT_Event
event =
new Event(_done_event);
162 throw_event(std::move(event));
180 compare_and_exchange(_future_state, (AtomicAdjust::Integer)FS_pending,
181 (AtomicAdjust::Integer)FS_locked_pending);
183 while (orig_state == FS_locked_pending) {
186 compare_and_exchange(_future_state, (AtomicAdjust::Integer)FS_pending,
187 (AtomicAdjust::Integer)FS_locked_pending);
190 if (orig_state == FS_pending) {
192 _result_ref = ref_ptr;
198 }
else if (orig_state == FS_cancelled) {
203 <<
"Ignoring set_result() called on cancelled " << *
this <<
"\n";
207 <<
"set_result() was called on finished " << *
this <<
"\n";
220 nassertr(task->is_runnable(),
false);
224 if (try_lock_pending()) {
225 if (_manager ==
nullptr) {
226 _manager = task->_manager;
229 _waiting.push_back(task);
233 nassertr(task->_manager ==
nullptr || task->_manager == _manager,
true);
248 if (manager ==
nullptr) {
252 if (manager ==
nullptr) {
258 switch (task->_state) {
259 case AsyncTask::S_servicing_removed:
260 nassertv(task->_manager == _manager);
263 task->_state = AsyncTask::S_servicing;
266 case AsyncTask::S_inactive:
268 nassertv(task->_manager ==
nullptr);
270 if (task_cat.is_debug()) {
272 <<
"Adding " << *task <<
" (woken by future " << *
this <<
")\n";
277 task->upon_birth(manager);
278 manager->_lock.
lock();
279 nassertv(task->_manager ==
nullptr &&
280 task->_state == AsyncTask::S_inactive);
282 AsyncTaskChain *chain = manager->do_find_task_chain(task->_chain_name);
283 if (chain ==
nullptr) {
285 <<
"Creating implicit AsyncTaskChain " << task->_chain_name
286 <<
" for " << manager->get_type() <<
" " << manager->get_name() <<
"\n";
287 chain = manager->do_make_task_chain(task->_chain_name);
293 case AsyncTask::S_awaiting:
294 nassertv(task->_manager == _manager);
295 task->_state = AsyncTask::S_active;
296 task->_chain->_active.push_back(task);
297 --task->_chain->_num_awaiting_tasks;
301 nassert_raise(
"unexpected task state");
309 AsyncGatheringFuture::
311 _futures(std::move(futures)),
314 bool any_pending =
false;
316 AsyncFuture::Futures::const_iterator it;
317 for (it = _futures.begin(); it != _futures.end(); ++it) {
322 if (fut->try_lock_pending()) {
323 if (_manager ==
nullptr) {
324 _manager = fut->_manager;
336 _future_state = (AtomicAdjust::Integer)FS_finished;
353 bool any_cancelled =
false;
354 AsyncFuture::Futures::const_iterator it;
355 for (it = _futures.begin(); it != _futures.end(); ++it) {
358 any_cancelled =
true;
364 if (set_future_state(FS_cancelled)) {
371 return any_cancelled;
static ClockObject * get_global_clock()
Returns a pointer to the global ClockObject.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This class represents a thread-safe handle to a promised future result of an asynchronous operation,...
An optional parameter associated with an event.
void notify_done(bool clean_exit)
Schedules the done callbacks.
A class to manage a loose queue of isolated tasks, which can be performed either synchronously (in th...
virtual ~AsyncFuture()
Destroys the future.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This is an abstract class that all classes which use TypeHandle, and also provide virtual functions t...
A lightweight class that can be used to automatically start and stop a PStatCollector around a sectio...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
A lightweight C++ object whose constructor calls acquire() and whose destructor calls release() on a ...
virtual bool cancel() override
Cancels all the futures.
void unlock()
Alias for release() to match C++11 semantics.
static void inc(Integer &var)
Atomically increments the indicated variable.
static void force_yield()
Suspends the current thread for the rest of the current epoch.
static bool dec(Integer &var)
Atomically decrements the indicated variable and returns true if the new value is nonzero,...
bool add_waiting_task(AsyncTask *task)
Indicates that the given task is waiting for this future to complete.
static AsyncFuture * gather(Futures futures)
Creates a new future that returns `done()` when all of the contained futures are done.
bool done() const
Returns true if the future is done or has been cancelled.
void wait()
Waits until the future is done.
A trivial implementation for atomic adjustments for systems that don't require multiprogramming,...
A ClockObject keeps track of elapsed real time and discrete time.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void set_result(std::nullptr_t)
Sets this future's result.
The AsyncTaskChain is a subset of the AsyncTaskManager.
static Integer get(const Integer &var)
Atomically retrieves the snapshot value of the indicated variable.
get_real_time
Returns the actual number of seconds elapsed since the ClockObject was created, or since it was last ...
Specific future that collects the results of several futures.
A base class for all things that want to be reference-counted.
This class represents a concrete task performed by an AsyncManager.
A named event, possibly with parameters.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
TypeHandle is the identifier used to differentiate C++ class types.
virtual bool cancel()
Cancels the future.
void lock()
Alias for acquire() to match C++11 semantics.
static AsyncTaskManager * get_global_ptr()
Returns a pointer to the global AsyncTaskManager.