#include "RegistrarThreadManager.h"
#include <RegistrarDefs.h>
#include <stdio.h>
#include "RegistrarThread.h"
#define DBG(x)
#define OUT printf
using namespace BPrivate;
RegistrarThreadManager::RegistrarThreadManager()
: fThreadCount(0)
{
}
RegistrarThreadManager::~RegistrarThreadManager()
{
KillThreads();
}
void
RegistrarThreadManager::MessageReceived(BMessage* message)
{
switch (message->what) {
case B_REG_MIME_UPDATE_THREAD_FINISHED:
{
CleanupThreads();
break;
}
default:
{
BHandler::MessageReceived(message);
break;
}
}
}
status_t
RegistrarThreadManager::LaunchThread(RegistrarThread *thread)
{
status_t err = thread ? B_OK : B_BAD_VALUE;
if (!err) {
if (atomic_add(&fThreadCount, 1) >= kThreadLimit) {
err = B_NO_MORE_THREADS;
atomic_add(&fThreadCount, -1);
}
}
if (!err) {
fThreads.push_back(thread);
err = thread->Run();
if (err) {
std::list<RegistrarThread*>::iterator i;
for (i = fThreads.begin(); i != fThreads.end();) {
if ((*i) == thread) {
i = fThreads.erase(i);
atomic_add(&fThreadCount, -1);
break;
} else
++i;
}
}
}
if (!err)
DBG(OUT("RegistrarThreadManager::LaunchThread(): launched new '%s'"
" thread, id %ld\n", thread->Name(), thread->Id()));
return err;
}
status_t
RegistrarThreadManager::CleanupThreads()
{
std::list<RegistrarThread*>::iterator i;
for (i = fThreads.begin(); i != fThreads.end(); ) {
if (*i) {
if ((*i)->IsFinished()) {
DBG(OUT("RegistrarThreadManager::CleanupThreads(): Cleaning up"
" thread %ld\n", (*i)->Id()));
RemoveThread(i);
} else
++i;
} else {
OUT("WARNING: RegistrarThreadManager::CleanupThreads(): NULL"
" mime_update_thread_shared_data pointer found in and removed"
" from RegistrarThreadManager::fThreads list\n");
i = fThreads.erase(i);
}
}
return B_OK;
}
status_t
RegistrarThreadManager::ShutdownThreads()
{
std::list<RegistrarThread*>::iterator i;
for (i = fThreads.begin(); i != fThreads.end(); ) {
if (*i) {
if ((*i)->IsFinished()) {
DBG(OUT("RegistrarThreadManager::ShutdownThreads(): Cleaning up"
" thread %ld\n", (*i)->Id()));
RemoveThread(i);
} else {
DBG(OUT("RegistrarThreadManager::ShutdownThreads(): Shutting"
" down thread %ld\n", (*i)->Id()));
(*i)->AskToExit();
++i;
}
} else {
OUT("WARNING: RegistrarThreadManager::ShutdownThreads(): NULL"
" mime_update_thread_shared_data pointer found in and removed"
" from RegistrarThreadManager::fThreads list\n");
i = fThreads.erase(i);
}
}
return B_OK;
}
status_t
RegistrarThreadManager::KillThreads()
{
std::list<RegistrarThread*>::iterator i;
for (i = fThreads.begin(); i != fThreads.end(); ) {
if (*i) {
if (!(*i)->IsFinished()) {
DBG(OUT("RegistrarThreadManager::KillThreads(): Killing thread"
" %ld\n", (*i)->Id()));
status_t err = kill_thread((*i)->Id());
if (err)
OUT("WARNING: RegistrarThreadManager::KillThreads():"
" kill_thread(%" B_PRId32 ") failed with error code"
" 0x%" B_PRIx32 "\n", (*i)->Id(), err);
}
DBG(OUT("RegistrarThreadManager::KillThreads(): Cleaning up thread"
" %ld\n", (*i)->Id()));
RemoveThread(i);
} else {
OUT("WARNING: RegistrarThreadManager::KillThreads(): NULL"
" mime_update_thread_shared_data pointer found in and removed"
" from RegistrarThreadManager::fThreads list\n");
i = fThreads.erase(i);
}
}
return B_OK;
}
uint
RegistrarThreadManager::ThreadCount() const
{
return fThreadCount;
}
std::list<RegistrarThread*>::iterator&
RegistrarThreadManager::RemoveThread(std::list<RegistrarThread*>::iterator &i)
{
status_t dummy;
wait_for_thread((*i)->Id(), &dummy);
delete *i;
atomic_add(&fThreadCount, -1);
return (i = fThreads.erase(i));
}