Go to the documentation of this file.
35 AsyncTaskManager(
const string &name) :
37 _lock(
"AsyncTaskManager::_lock"),
43 do_make_task_chain(
"default");
62 if (task_cat.is_debug()) {
63 do_output(task_cat.debug());
70 while (!_task_chains.
empty()) {
78 if (_num_tasks == 1) {
79 nassertv(_tasks_by_name.size() == 1);
80 TasksByName::const_iterator tbni = _tasks_by_name.begin();
82 nassertv(task->_state == AsyncTask::S_servicing ||
83 task->_state == AsyncTask::S_servicing_removed);
84 task->_state = AsyncTask::S_servicing_removed;
89 nassertd(_num_tasks == 0 && _tasks_by_name.empty()) {
91 <<
"_num_tasks = " << _num_tasks <<
" _tasks_by_name = " << _tasks_by_name.size() <<
"\n";
92 TasksByName::const_iterator tbni;
93 for (tbni = _tasks_by_name.begin();
94 tbni != _tasks_by_name.end();
97 <<
" " << *(*tbni) <<
"\n";
110 return _task_chains.
size();
119 nassertr(n >= 0 && n < (
int)_task_chains.
size(),
nullptr);
120 return _task_chains[n];
131 return do_make_task_chain(name);
141 return do_find_task_chain(name);
155 TaskChains::iterator tci = _task_chains.find(chain);
156 if (tci == _task_chains.
end()) {
163 while (chain->_num_tasks != 0) {
166 <<
"Waiting for tasks on chain " << name <<
" to finish.\n";
167 chain->do_wait_for_tasks();
172 _task_chains.erase(tci);
182 nassertv(task->is_runnable());
187 if (task_cat.is_debug()) {
189 <<
"Adding " << *task <<
"\n";
192 if (task->_state == AsyncTask::S_servicing_removed) {
193 if (task->_manager ==
this) {
196 task->_state = AsyncTask::S_servicing;
201 nassertv(task->_manager ==
nullptr &&
202 task->_state == AsyncTask::S_inactive);
203 nassertv(!do_has_task(task));
206 task->upon_birth(
this);
208 nassertv(task->_manager ==
nullptr &&
209 task->_state == AsyncTask::S_inactive);
210 nassertv(!do_has_task(task));
213 if (chain ==
nullptr) {
215 <<
"Creating implicit AsyncTaskChain " << task->_chain_name
216 <<
" for " << get_type() <<
" " << get_name() <<
"\n";
217 chain = do_make_task_chain(task->_chain_name);
231 if (task->_manager !=
this) {
232 nassertr(!do_has_task(task),
false);
236 if (task->_state == AsyncTask::S_servicing_removed) {
257 TasksByName::const_iterator tbni = _tasks_by_name.lower_bound(&sample_task);
258 if (tbni != _tasks_by_name.end() && (*tbni)->get_name() == name) {
273 TasksByName::const_iterator tbni = _tasks_by_name.lower_bound(&sample_task);
275 while (tbni != _tasks_by_name.end() && (*tbni)->get_name() == name) {
293 TasksByName::const_iterator tbni = _tasks_by_name.lower_bound(&sample_task);
295 while (tbni != _tasks_by_name.end() && (*tbni)->get_name().substr(0, prefix.size()) == prefix) {
297 if (pattern.
matches(task->get_name())) {
322 size_t num_removed = 0;
325 for (
size_t i = 0; i < num_tasks; ++i) {
328 if (task->_manager !=
this) {
330 nassertr(!do_has_task(task), num_removed);
332 nassertr(task->_chain->_manager ==
this, num_removed);
333 if (task_cat.is_debug()) {
335 <<
"Removing " << *task <<
"\n";
337 if (task->_chain->do_remove(task,
true)) {
340 if (task_cat.is_debug()) {
342 <<
" (unable to remove " << *task <<
")\n";
359 while (_num_tasks > 0) {
363 for (
unsigned int i = 0; i < _task_chains.
size(); ++i) {
365 chain->do_wait_for_tasks();
382 for (
unsigned int i = 0; i < _task_chains.
size(); ++i) {
384 chain->do_stop_threads();
400 for (
unsigned int i = 0; i < _task_chains.
size(); ++i) {
403 chain->do_start_threads();
416 TaskChains::const_iterator tci;
417 for (tci = _task_chains.
begin();
418 tci != _task_chains.
end();
437 TaskChains::const_iterator tci;
438 for (tci = _task_chains.
begin();
439 tci != _task_chains.
end();
457 TaskChains::const_iterator tci;
458 for (tci = _task_chains.
begin();
459 tci != _task_chains.
end();
480 for (
unsigned int i = 0; i < _task_chains.
size(); ++i) {
484 if (chain->_state == AsyncTaskChain::S_interrupted) {
505 bool got_any =
false;
506 double next_wake_time = -1.0;
508 TaskChains::const_iterator tci;
509 for (tci = _task_chains.
begin();
510 tci != _task_chains.
end();
513 double time = chain->do_get_next_wake_time();
517 next_wake_time = time;
519 next_wake_time = std::min(time, next_wake_time);
524 return next_wake_time;
530 void AsyncTaskManager::
531 output(std::ostream &out)
const {
539 void AsyncTaskManager::
540 write(std::ostream &out,
int indent_level)
const {
543 << get_type() <<
" " << get_name() <<
"\n";
545 TaskChains::const_iterator tci;
546 for (tci = _task_chains.
begin();
547 tci != _task_chains.
end();
550 if (chain->_num_tasks != 0) {
552 chain->do_write(out, indent_level + 2);
565 do_make_task_chain(
const string &name) {
568 TaskChains::const_iterator tci = _task_chains.insert(chain).first;
579 do_find_task_chain(
const string &name) {
582 TaskChains::const_iterator tci = _task_chains.find(chain);
583 if (tci != _task_chains.
end()) {
593 void AsyncTaskManager::
595 if (!task->get_name().empty()) {
597 TasksByName::iterator tbni = _tasks_by_name.lower_bound(task);
598 while (tbni != _tasks_by_name.end()) {
599 if ((*tbni) == task) {
600 _tasks_by_name.erase(tbni);
603 if ((*tbni)->get_name() != task->get_name()) {
621 bool AsyncTaskManager::
623 TaskChains::const_iterator tci;
624 for (tci = _task_chains.
begin();
625 tci != _task_chains.
end();
628 if (chain->do_has_task(task)) {
639 void AsyncTaskManager::
640 do_output(std::ostream &out)
const {
641 out << get_type() <<
" " << get_name()
642 <<
"; " << _num_tasks <<
" tasks";
648 void AsyncTaskManager::
650 nassertv(_global_ptr ==
nullptr);
A lightweight C++ object whose constructor calls acquire() and whose destructor calls release() on a ...
size_type_0 size() const
Returns the number of elements in the ordered vector.
get_num_task_chains
Returns the number of different task chains.
std::ostream & indent(std::ostream &out, int indent_level)
A handy function for doing text formatting.
void wait_for_tasks()
Blocks until the task list is empty.
The AsyncTaskChain is a subset of the AsyncTaskManager.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
AsyncTaskChain * make_task_chain(const std::string &name)
Creates a new AsyncTaskChain of the indicated name and stores it within the AsyncTaskManager.
get_num_tasks
Returns the number of AsyncTasks in the collection.
AsyncTask * find_task(const std::string &name) const
Returns the first task found with the indicated name, or NULL if there is no task with the indicated ...
get_next_wake_time
Returns the scheduled time (on the manager's clock) of the next sleeping task, on any task chain,...
A ClockObject keeps track of elapsed real time and discrete time.
void lock()
Alias for acquire() to match C++11 semantics.
A list of tasks, for instance as returned by some of the AsyncTaskManager query functions.
bool empty() const
Returns true if the ordered vector is empty, false otherwise.
iterator_0 begin()
Returns the iterator that marks the first element in the ordered vector.
get_active_tasks
Returns the set of tasks that are active (and not sleeping) on the task manager, at the time of the c...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
get_sleeping_tasks
Returns the set of tasks that are sleeping (and not active) on the task manager, at the time of the c...
bool matches(const std::string &candidate) const
Returns true if the candidate string matches the pattern, false otherwise.
AsyncTaskCollection find_tasks(const std::string &name) const
Returns the list of tasks found with the indicated name.
void add_tasks_from(const AsyncTaskCollection &other)
Adds all the AsyncTasks indicated in the other collection to this task.
iterator_0 end()
Returns the iterator that marks the end of the ordered vector.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void cleanup()
Stops all threads and messily empties the task list.
TypeHandle is the identifier used to differentiate C++ class types.
void start_threads()
Starts any requested threads to service the tasks on the queue.
bool remove_task_chain(const std::string &name)
Removes the AsyncTaskChain of the indicated name.
get_task
Returns the nth AsyncTask in the collection.
This class represents a concrete task performed by an AsyncManager.
void unlock()
Alias for release() to match C++11 semantics.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
std::string get_const_prefix() const
Returns the initial part of the pattern before the first glob character.
bool remove()
Removes the task from its active manager, if any, and makes the state S_inactive (or possible S_servi...
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
void poll()
Runs through all the tasks in the task list, once, if the task manager is running in single-threaded ...
void ref() const
Explicitly increments the reference count.
A class to manage a loose queue of isolated tasks, which can be performed either synchronously (in th...
get_task_chain
Returns the nth task chain.
void add(AsyncTask *task)
Adds the indicated task to the active queue.
bool has_task(AsyncTask *task) const
Returns true if the indicated task has been added to this AsyncTaskManager, false otherwise.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
A base class for all things which can have a name.
AsyncTaskCollection find_tasks_matching(const GlobPattern &pattern) const
Returns the list of tasks found whose name matches the indicated glob pattern, e.g.
void local_object()
This function should be called, once, immediately after creating a new instance of some ReferenceCoun...
AsyncTaskChain * find_task_chain(const std::string &name)
Searches a new AsyncTaskChain of the indicated name and returns it if it exists, or NULL otherwise.
get_tasks
Returns the set of tasks that are active or sleeping on the task manager, at the time of the call.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
bool remove(AsyncTask *task)
Removes the indicated task from the active queue.
void stop_threads()
Stops any threads that are currently running.
This class can be used to test for string matches against standard Unix- shell filename globbing conv...
void notify_all()
Informs all of the other threads who are currently blocked on wait() that the relevant condition has ...
void pop_back()
Removes the last element at the end of the vector.
void add_task(AsyncTask *task)
Adds a new AsyncTask to the collection.