From e177c2c89aaf4526802e5b8ec3397938a6fac498 Mon Sep 17 00:00:00 2001 From: Tyler Dauwalder Date: Sun, 29 Sep 2002 07:11:20 +0000 Subject: [PATCH] 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 --- src/servers/registrar/ThreadManager.cpp | 206 ++++++++++++++++++++++++ src/servers/registrar/ThreadManager.h | 43 +++++ 2 files changed, 249 insertions(+) create mode 100644 src/servers/registrar/ThreadManager.cpp create mode 100644 src/servers/registrar/ThreadManager.h diff --git a/src/servers/registrar/ThreadManager.cpp b/src/servers/registrar/ThreadManager.cpp new file mode 100644 index 0000000000..419d56dc64 --- /dev/null +++ b/src/servers/registrar/ThreadManager.cpp @@ -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 +#include + +#include + +#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::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::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::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::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::iterator &i) +{ + delete *i; + fThreads.erase(i); + fThreadCount--; +} + diff --git a/src/servers/registrar/ThreadManager.h b/src/servers/registrar/ThreadManager.h new file mode 100644 index 0000000000..8742d089d0 --- /dev/null +++ b/src/servers/registrar/ThreadManager.h @@ -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 +#include + +#include + +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::iterator &i); + + std::list fThreads; + uint fThreadCount; +}; + +#endif // THREAD_MANAGER_H