mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-03 10:22:45 -04:00
add stop_threads() etc
This commit is contained in:
parent
ee45d77be1
commit
197032bd70
@ -17,20 +17,32 @@
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: AsyncTaskManager::is_started
|
||||||
|
// Access: Published
|
||||||
|
// Description: Returns true if the thread(s) have been started and
|
||||||
|
// are ready to service requests, false otherwise. If
|
||||||
|
// this is false, the next call to add() or add_and_do()
|
||||||
|
// will automatically start the threads.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
INLINE bool AsyncTaskManager::
|
||||||
|
is_started() const {
|
||||||
|
return (_state == S_started);
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: AsyncTaskManager::get_num_threads
|
// Function: AsyncTaskManager::get_num_threads
|
||||||
// Access: Published
|
// Access: Published
|
||||||
// Description: Returns the number of threads that have been created
|
// Description: Returns the number of threads that have been created
|
||||||
// to service the tasks within this task manager.
|
// to service the tasks within this task manager. This
|
||||||
|
// will return 0 before the threads have been started;
|
||||||
|
// it will also return 0 if thread support is not
|
||||||
|
// available.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
INLINE int AsyncTaskManager::
|
INLINE int AsyncTaskManager::
|
||||||
get_num_threads() const {
|
get_num_threads() const {
|
||||||
#ifdef HAVE_THREADS
|
MutexHolder holder(_lock);
|
||||||
return _num_threads;
|
return _threads.size();
|
||||||
#else
|
|
||||||
// Without threading support, this is always 0 threads.
|
|
||||||
return 0;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
|
@ -53,19 +53,58 @@ AsyncTaskManager(const string &name, int num_threads) :
|
|||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
AsyncTaskManager::
|
AsyncTaskManager::
|
||||||
~AsyncTaskManager() {
|
~AsyncTaskManager() {
|
||||||
|
stop_threads();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: AsyncTaskManager::stop_threads
|
||||||
|
// Access: Published
|
||||||
|
// Description: Stops any threads that are currently running. If any
|
||||||
|
// tasks are still pending and have not yet been picked
|
||||||
|
// up by a thread, they will not be serviced unless
|
||||||
|
// poll() or start_threads() is later called.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void AsyncTaskManager::
|
||||||
|
stop_threads() {
|
||||||
if (_state == S_started) {
|
if (_state == S_started) {
|
||||||
// Clean up all of the threads.
|
// Clean up all of the threads.
|
||||||
MutexHolder holder(_lock);
|
MutexHolder holder(_lock);
|
||||||
_state = S_shutdown;
|
if (_state == S_started) {
|
||||||
_cvar.signal_all();
|
_state = S_shutdown;
|
||||||
|
_cvar.signal_all();
|
||||||
|
|
||||||
Threads::iterator ti;
|
Threads wait_threads;
|
||||||
for (ti = _threads.begin(); ti != _threads.end(); ++ti) {
|
wait_threads.swap(_threads);
|
||||||
(*ti)->join();
|
|
||||||
|
// We have to release the lock while we join, so the threads can
|
||||||
|
// wake up and see that we're shutting down.
|
||||||
|
_lock.release();
|
||||||
|
Threads::iterator ti;
|
||||||
|
for (ti = wait_threads.begin(); ti != wait_threads.end(); ++ti) {
|
||||||
|
(*ti)->join();
|
||||||
|
}
|
||||||
|
_lock.lock();
|
||||||
|
|
||||||
|
_state = S_initial;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: AsyncTaskManager::start_threads
|
||||||
|
// Access: Published
|
||||||
|
// Description: Starts any requested threads to service the tasks on
|
||||||
|
// the queue. This is normally not necessary, since
|
||||||
|
// adding a task will start the threads automatically.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void AsyncTaskManager::
|
||||||
|
start_threads() {
|
||||||
|
if (_state == S_initial) {
|
||||||
|
MutexHolder holder(_lock);
|
||||||
|
do_start_threads();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: AsyncTaskManager::add
|
// Function: AsyncTaskManager::add
|
||||||
// Access: Published
|
// Access: Published
|
||||||
@ -81,19 +120,7 @@ add(AsyncTask *task) {
|
|||||||
task->_state == AsyncTask::S_inactive);
|
task->_state == AsyncTask::S_inactive);
|
||||||
nassertv(find_task(task) == -1);
|
nassertv(find_task(task) == -1);
|
||||||
|
|
||||||
// Attempt to start the threads, if we haven't already.
|
do_start_threads();
|
||||||
if (_state == S_initial) {
|
|
||||||
_state = S_started;
|
|
||||||
if (Thread::is_threading_supported()) {
|
|
||||||
_threads.reserve(_num_threads);
|
|
||||||
for (int i = 0; i < _num_threads; ++i) {
|
|
||||||
PT(AsyncTaskManagerThread) thread = new AsyncTaskManagerThread(this);
|
|
||||||
if (thread->start(TP_low, true)) {
|
|
||||||
_threads.push_back(thread);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
task->_manager = this;
|
task->_manager = this;
|
||||||
task->_state = AsyncTask::S_active;
|
task->_state = AsyncTask::S_active;
|
||||||
@ -118,7 +145,7 @@ add(AsyncTask *task) {
|
|||||||
// execute the task before returning in the non-threaded
|
// execute the task before returning in the non-threaded
|
||||||
// case. In the threaded case, this method behaves
|
// case. In the threaded case, this method behaves
|
||||||
// exactly the same as add().
|
// exactly the same as add().
|
||||||
|
//
|
||||||
// The return value is true if the task has been added
|
// The return value is true if the task has been added
|
||||||
// and is still pending, false if it has completed.
|
// and is still pending, false if it has completed.
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
@ -130,19 +157,7 @@ add_and_do(AsyncTask *task) {
|
|||||||
task->_state == AsyncTask::S_inactive, false);
|
task->_state == AsyncTask::S_inactive, false);
|
||||||
nassertr(find_task(task) == -1, false);
|
nassertr(find_task(task) == -1, false);
|
||||||
|
|
||||||
// Attempt to start the threads, if we haven't already.
|
do_start_threads();
|
||||||
if (_state == S_initial) {
|
|
||||||
_state = S_started;
|
|
||||||
if (Thread::is_threading_supported()) {
|
|
||||||
_threads.reserve(_num_threads);
|
|
||||||
for (int i = 0; i < _num_threads; ++i) {
|
|
||||||
PT(AsyncTaskManagerThread) thread = new AsyncTaskManagerThread(this);
|
|
||||||
if (thread->start(TP_low, true)) {
|
|
||||||
_threads.push_back(thread);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
task->_manager = this;
|
task->_manager = this;
|
||||||
task->_state = AsyncTask::S_active;
|
task->_state = AsyncTask::S_active;
|
||||||
@ -232,7 +247,7 @@ has_task(AsyncTask *task) const {
|
|||||||
void AsyncTaskManager::
|
void AsyncTaskManager::
|
||||||
poll() {
|
poll() {
|
||||||
MutexHolder holder(_lock);
|
MutexHolder holder(_lock);
|
||||||
if (_threads.empty()) {
|
if (!_threads.empty()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -389,6 +404,28 @@ task_done(AsyncTask *task) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: AsyncTaskManager::do_start_threads
|
||||||
|
// Access: Protected
|
||||||
|
// Description: The private implementation of start_threads; assumes
|
||||||
|
// the lock is already held.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void AsyncTaskManager::
|
||||||
|
do_start_threads() {
|
||||||
|
if (_state == S_initial) {
|
||||||
|
_state = S_started;
|
||||||
|
if (Thread::is_threading_supported()) {
|
||||||
|
_threads.reserve(_num_threads);
|
||||||
|
for (int i = 0; i < _num_threads; ++i) {
|
||||||
|
PT(AsyncTaskManagerThread) thread = new AsyncTaskManagerThread(this);
|
||||||
|
if (thread->start(TP_low, true)) {
|
||||||
|
_threads.push_back(thread);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////
|
||||||
// Function: AsyncTaskManager::AsyncTaskManagerThread::Constructor
|
// Function: AsyncTaskManager::AsyncTaskManagerThread::Constructor
|
||||||
// Access: Public
|
// Access: Public
|
||||||
|
@ -53,6 +53,9 @@ PUBLISHED:
|
|||||||
virtual ~AsyncTaskManager();
|
virtual ~AsyncTaskManager();
|
||||||
|
|
||||||
INLINE int get_num_threads() const;
|
INLINE int get_num_threads() const;
|
||||||
|
BLOCKING void stop_threads();
|
||||||
|
void start_threads();
|
||||||
|
INLINE bool is_started() const;
|
||||||
|
|
||||||
void add(AsyncTask *task);
|
void add(AsyncTask *task);
|
||||||
bool add_and_do(AsyncTask *task);
|
bool add_and_do(AsyncTask *task);
|
||||||
@ -72,7 +75,9 @@ protected:
|
|||||||
int find_task(AsyncTask *task) const;
|
int find_task(AsyncTask *task) const;
|
||||||
void service_one_task(AsyncTaskManagerThread *thread);
|
void service_one_task(AsyncTaskManagerThread *thread);
|
||||||
void task_done(AsyncTask *task);
|
void task_done(AsyncTask *task);
|
||||||
|
void do_start_threads();
|
||||||
|
|
||||||
|
protected:
|
||||||
class AsyncTaskManagerThread : public Thread {
|
class AsyncTaskManagerThread : public Thread {
|
||||||
public:
|
public:
|
||||||
AsyncTaskManagerThread(AsyncTaskManager *manager);
|
AsyncTaskManagerThread(AsyncTaskManager *manager);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user