ThreadManager class, which is responsible for managing all the
RegistrarThread objects created by the registrar. git-svn-id: file:///srv/svn/repos/haiku/trunk/current@1269 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
162f340b21
commit
e177c2c89a
206
src/servers/registrar/ThreadManager.cpp
Normal file
206
src/servers/registrar/ThreadManager.cpp
Normal file
@ -0,0 +1,206 @@
|
|||||||
|
//----------------------------------------------------------------------
|
||||||
|
// This software is part of the OpenBeOS distribution and is covered
|
||||||
|
// by the OpenBeOS license.
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
/*!
|
||||||
|
\file ThreadManager.cpp
|
||||||
|
ThreadManager implementation
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "ThreadManager.h"
|
||||||
|
|
||||||
|
#include <RegistrarDefs.h>
|
||||||
|
#include <RegistrarThread.h>
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#define DBG(x) x
|
||||||
|
//#define DBG(x)
|
||||||
|
#define OUT printf
|
||||||
|
|
||||||
|
/*!
|
||||||
|
\class ThreadManager
|
||||||
|
\brief ThreadManager is the master of all threads spawned by the registrar
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
//! Creates a new ThreadManager object
|
||||||
|
ThreadManager::ThreadManager()
|
||||||
|
: fThreadCount(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// destructor
|
||||||
|
/*! \brief Destroys the ThreadManager object, killing and deleting any still
|
||||||
|
running threads.
|
||||||
|
*/
|
||||||
|
ThreadManager::~ThreadManager()
|
||||||
|
{
|
||||||
|
KillThreads();
|
||||||
|
}
|
||||||
|
|
||||||
|
// MessageReceived
|
||||||
|
/*! \brief Handles \c B_REG_MIME_UPDATE_THREAD_FINISHED messages, passing on all others.
|
||||||
|
|
||||||
|
Each \c B_REG_MIME_UPDATE_THREAD_FINISHED message triggers a call to CleanupThreads().
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
ThreadManager::MessageReceived(BMessage* message)
|
||||||
|
{
|
||||||
|
switch (message->what) {
|
||||||
|
case B_REG_MIME_UPDATE_THREAD_FINISHED:
|
||||||
|
{
|
||||||
|
CleanupThreads();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
BHandler::MessageReceived(message);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// LaunchThread
|
||||||
|
/*! \brief Launches the given thread, passing responsiblity for it onto the
|
||||||
|
ThreadManager object.
|
||||||
|
|
||||||
|
\param thread Pointer to a newly allocated \c RegistrarThread object.
|
||||||
|
|
||||||
|
If the result of the function is \c B_OK, the \c ThreadManager object
|
||||||
|
assumes ownership of \a thread; if the result is an error code, it
|
||||||
|
does not.
|
||||||
|
|
||||||
|
\return
|
||||||
|
- \c B_OK: success
|
||||||
|
- \c B_NO_MORE_THREADS: the number of concurrently allowed threads (defined by
|
||||||
|
ThreadManager::kThreadLimit) has already been reached
|
||||||
|
- \c B_BAD_THREAD_STATE: the thread has already been launched
|
||||||
|
- other error code: failure
|
||||||
|
*/
|
||||||
|
status_t
|
||||||
|
ThreadManager::LaunchThread(RegistrarThread *thread)
|
||||||
|
{
|
||||||
|
status_t err = thread ? B_OK : B_BAD_VALUE;
|
||||||
|
if (!err)
|
||||||
|
err = fThreadCount < kThreadLimit ? B_OK : B_NO_MORE_THREADS;
|
||||||
|
|
||||||
|
if (!err) {
|
||||||
|
fThreads.push_back(thread);
|
||||||
|
fThreadCount++;
|
||||||
|
err = thread->Run();
|
||||||
|
if (err) {
|
||||||
|
std::list<RegistrarThread*>::iterator i;
|
||||||
|
for (i = fThreads.begin(); i != fThreads.end(); i++) {
|
||||||
|
if ((*i) == thread) {
|
||||||
|
fThreads.erase(i);
|
||||||
|
fThreadCount--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!err)
|
||||||
|
DBG(OUT("launched new %s thread, id == %ld\n", thread->Name(), thread->Id()));
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
// CleanupThreads
|
||||||
|
/*! \brief Frees the resources of any threads that are no longer running
|
||||||
|
|
||||||
|
\todo This function should perhaps be triggered periodically by a
|
||||||
|
BMessageRunner once we have our own BMessageRunner implementation.
|
||||||
|
*/
|
||||||
|
status_t
|
||||||
|
ThreadManager::CleanupThreads()
|
||||||
|
{
|
||||||
|
status_t err = B_ENTRY_NOT_FOUND;
|
||||||
|
std::list<RegistrarThread*>::iterator i;
|
||||||
|
for (i = fThreads.begin(); i != fThreads.end(); i++) {
|
||||||
|
if (*i) {
|
||||||
|
if ((*i)->IsFinished()) {
|
||||||
|
OUT("Cleaning up thread %ld\n", (*i)->Id());
|
||||||
|
RemoveThread(i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
OUT("WARNING: ThreadManager::CleanupThreads(): NULL mime_update_thread_shared_data "
|
||||||
|
"pointer found in and removed from ThreadManager::fThreads list\n");
|
||||||
|
fThreads.erase(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ShutdownThreads
|
||||||
|
/*! \brief Requests that any running threads quit and frees the resources
|
||||||
|
of any threads that are no longer running.
|
||||||
|
|
||||||
|
\todo This function should be called during system shutdown around
|
||||||
|
the same time as global B_QUIT_REQUESTED messages are sent out.
|
||||||
|
*/
|
||||||
|
status_t
|
||||||
|
ThreadManager::ShutdownThreads()
|
||||||
|
{
|
||||||
|
status_t err = B_ENTRY_NOT_FOUND;
|
||||||
|
std::list<RegistrarThread*>::iterator i;
|
||||||
|
for (i = fThreads.begin(); i != fThreads.end(); i++) {
|
||||||
|
if (*i) {
|
||||||
|
if ((*i)->IsFinished())
|
||||||
|
RemoveThread(i);
|
||||||
|
else
|
||||||
|
(*i)->AskToExit();
|
||||||
|
} else {
|
||||||
|
OUT("WARNING: ThreadManager::ShutdownThreads(): NULL mime_update_thread_shared_data "
|
||||||
|
"pointer found in and removed from ThreadManager::fThreads list\n");
|
||||||
|
fThreads.erase(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*! \todo We may want to iterate back through the list at this point,
|
||||||
|
snooze for a moment if find an unfinished thread, and kill it if
|
||||||
|
it still isn't finished by the time we're done snoozing.
|
||||||
|
*/
|
||||||
|
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
// KillThreads
|
||||||
|
/*! \brief Kills any running threads and frees their resources.
|
||||||
|
|
||||||
|
\todo This function should probably be called during system shutdown
|
||||||
|
just before kernel shutdown begins.
|
||||||
|
*/
|
||||||
|
status_t
|
||||||
|
ThreadManager::KillThreads()
|
||||||
|
{
|
||||||
|
std::list<RegistrarThread*>::iterator i;
|
||||||
|
for (i = fThreads.begin(); i != fThreads.end(); i++) {
|
||||||
|
if (*i) {
|
||||||
|
if (!(*i)->IsFinished()) {
|
||||||
|
status_t err = kill_thread((*i)->Id());
|
||||||
|
if (err)
|
||||||
|
OUT("WARNING: ThreadManager::KillThreads(): kill_thread(%ld) failed with "
|
||||||
|
"error code 0x%lx\n", (*i)->Id(), err);
|
||||||
|
}
|
||||||
|
RemoveThread(i);
|
||||||
|
} else {
|
||||||
|
OUT("WARNING: ThreadManager::KillThreads(): NULL mime_update_thread_shared_data "
|
||||||
|
"pointer found in and removed from ThreadManager::fThreads list\n");
|
||||||
|
fThreads.erase(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
// RemoveThread
|
||||||
|
/*! \brief Deletes the given thread and removes it from the thread list.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
ThreadManager::RemoveThread(std::list<RegistrarThread*>::iterator &i)
|
||||||
|
{
|
||||||
|
delete *i;
|
||||||
|
fThreads.erase(i);
|
||||||
|
fThreadCount--;
|
||||||
|
}
|
||||||
|
|
43
src/servers/registrar/ThreadManager.h
Normal file
43
src/servers/registrar/ThreadManager.h
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
//----------------------------------------------------------------------
|
||||||
|
// This software is part of the OpenBeOS distribution and is covered
|
||||||
|
// by the OpenBeOS license.
|
||||||
|
//---------------------------------------------------------------------
|
||||||
|
/*!
|
||||||
|
\file ThreadManager.h
|
||||||
|
ThreadManager interface declaration
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef THREAD_MANAGER_H
|
||||||
|
#define THREAD_MANAGER_H
|
||||||
|
|
||||||
|
#include <Handler.h>
|
||||||
|
#include <SupportDefs.h>
|
||||||
|
|
||||||
|
#include <list>
|
||||||
|
|
||||||
|
class RegistrarThread;
|
||||||
|
|
||||||
|
class ThreadManager : public BHandler {
|
||||||
|
public:
|
||||||
|
ThreadManager();
|
||||||
|
~ThreadManager();
|
||||||
|
|
||||||
|
// BHandler virtuals
|
||||||
|
virtual void MessageReceived(BMessage* message);
|
||||||
|
|
||||||
|
// Thread management functions
|
||||||
|
status_t LaunchThread(RegistrarThread *thread);
|
||||||
|
status_t CleanupThreads();
|
||||||
|
status_t ShutdownThreads();
|
||||||
|
status_t KillThreads();
|
||||||
|
|
||||||
|
private:
|
||||||
|
static const uint kThreadLimit = 12;
|
||||||
|
|
||||||
|
void RemoveThread(std::list<RegistrarThread*>::iterator &i);
|
||||||
|
|
||||||
|
std::list<RegistrarThread*> fThreads;
|
||||||
|
uint fThreadCount;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // THREAD_MANAGER_H
|
Loading…
Reference in New Issue
Block a user