* Got rid of Map, and replaced it with a std::map.

* Cleanup.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@34549 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2009-12-08 09:40:58 +00:00
parent d9e9ff142b
commit 6fcead13eb
2 changed files with 144 additions and 133 deletions
+110 -102
View File
@@ -27,99 +27,84 @@
*
*/
#include <OS.h>
#include <Application.h>
#include <Roster.h>
#include <Messenger.h>
#include <Autolock.h>
#include <stdio.h>
#include "debug.h"
#include "MediaMisc.h"
#include "AppManager.h"
#include "NodeManager.h"
#include <stdio.h>
#include <Application.h>
#include <Autolock.h>
#include <OS.h>
#include <Roster.h>
#include <debug.h>
#include <MediaMisc.h>
#include "BufferManager.h"
#include "NotificationManager.h"
#include "media_server.h"
#include "NodeManager.h"
#include "NotificationManager.h"
AppManager::AppManager()
:
BLocker("media app manager")
{
fAppMap = new Map<team_id, App>;
fLocker = new BLocker("app manager locker");
fQuit = create_sem(0, "big brother waits");
fBigBrother = spawn_thread(bigbrother, "big brother is watching you", B_NORMAL_PRIORITY, this);
fBigBrother = spawn_thread(_BigBrotherEntry, "big brother is watching you",
B_NORMAL_PRIORITY, this);
resume_thread(fBigBrother);
}
AppManager::~AppManager()
{
status_t err;
delete_sem(fQuit);
wait_for_thread(fBigBrother, &err);
delete fLocker;
delete fAppMap;
wait_for_thread(fBigBrother, NULL);
}
bool
AppManager::HasTeam(team_id team)
{
BAutolock lock(fLocker);
return fAppMap->Has(team);
BAutolock lock(this);
return fMap.find(team) != fMap.end();
}
status_t
AppManager::RegisterTeam(team_id team, BMessenger messenger)
AppManager::RegisterTeam(team_id team, const BMessenger& messenger)
{
BAutolock lock(fLocker);
BAutolock lock(this);
TRACE("AppManager::RegisterTeam %ld\n", team);
if (HasTeam(team)) {
ERROR("AppManager::RegisterTeam: team %ld already registered\n", team);
return B_ERROR;
}
App app;
app.team = team;
app.messenger = messenger;
return fAppMap->Insert(team, app) ? B_OK : B_ERROR;
try {
fMap.insert(std::make_pair(team, messenger));
} catch (std::bad_alloc& exception) {
return B_NO_MEMORY;
}
return B_OK;
}
status_t
AppManager::UnregisterTeam(team_id team)
{
bool is_removed;
TRACE("AppManager::UnregisterTeam %ld\n", team);
fLocker->Lock();
is_removed = fAppMap->Remove(team);
fLocker->Unlock();
CleanupTeam(team);
return is_removed ? B_OK : B_ERROR;
}
Lock();
bool isRemoved = fMap.erase(team) != 0;
Unlock();
status_t
AppManager::SendMessage(team_id team, BMessage *msg)
{
BAutolock lock(fLocker);
App *app;
if (!fAppMap->Get(team, &app))
return B_ERROR;
return app->messenger.SendMessage(msg);
}
_CleanupTeam(team);
void
AppManager::TeamDied(team_id team)
{
CleanupTeam(team);
fLocker->Lock();
fAppMap->Remove(team);
fLocker->Unlock();
return isRemoved ? B_OK : B_ERROR;
}
@@ -135,55 +120,44 @@ AppManager::AddonServerTeam()
}
//=========================================================================
// The BigBrother thread send ping messages to the BMediaRoster of
// all currently running teams. If the reply times out or is wrong,
// the team cleanup function TeamDied() will be called.
//=========================================================================
int32
AppManager::bigbrother(void *self)
status_t
AppManager::SendMessage(team_id team, BMessage* message)
{
static_cast<AppManager *>(self)->BigBrother();
return 0;
BAutolock lock(this);
AppMap::iterator found = fMap.find(team);
if (found == fMap.end())
return B_NAME_NOT_FOUND;
return found->second.SendMessage(message);
}
void
AppManager::BigBrother()
AppManager::Dump()
{
status_t status;
BMessage msg('PING');
BMessage reply;
team_id team;
App *app;
do {
if (!fLocker->Lock())
break;
for (fAppMap->Rewind(); fAppMap->GetNext(&app); ) {
reply.what = 0;
status = app->messenger.SendMessage(&msg, &reply, 5000000, 2000000);
if (status != B_OK || reply.what != 'PONG') {
team = app->team;
fLocker->Unlock();
TeamDied(team);
continue;
}
}
fLocker->Unlock();
status = acquire_sem_etc(fQuit, 1, B_RELATIVE_TIMEOUT, 2000000);
} while (status == B_TIMED_OUT || status == B_INTERRUPTED);
BAutolock lock(this);
printf("\n");
printf("AppManager: list of applications follows:\n");
app_info info;
AppMap::iterator iterator = fMap.begin();
for (; iterator != fMap.end(); iterator++) {
app_info info;
be_roster->GetRunningAppInfo(iterator->first, &info);
printf(" team %ld \"%s\", messenger %svalid\n", iterator->first,
info.ref.name, iterator->second.IsValid() ? "" : "NOT ");
}
printf("AppManager: list end\n");
}
//=========================================================================
// The following functions must be called unlocked.
// They clean up after a crash, or start/terminate the media_addon_server.
//=========================================================================
void
AppManager::CleanupTeam(team_id team)
AppManager::_CleanupTeam(team_id team)
{
ASSERT(false == fLocker->IsLocked());
ASSERT(!IsLocked());
TRACE("AppManager: cleaning up team %ld\n", team);
@@ -194,16 +168,50 @@ AppManager::CleanupTeam(team_id team)
void
AppManager::Dump()
AppManager::_TeamDied(team_id team)
{
BAutolock lock(fLocker);
printf("\n");
printf("AppManager: list of applications follows:\n");
App *app;
app_info info;
for (fAppMap->Rewind(); fAppMap->GetNext(&app); ) {
be_roster->GetRunningAppInfo(app->team, &info);
printf(" team %ld \"%s\", messenger %svalid\n", app->team, info.ref.name, app->messenger.IsValid() ? "" : "NOT ");
}
printf("AppManager: list end\n");
UnregisterTeam(team);
}
status_t
AppManager::_BigBrotherEntry(void* self)
{
static_cast<AppManager*>(self)->_BigBrother();
return 0;
}
/*! The BigBrother thread send ping messages to the BMediaRoster of
all currently running teams. If the reply times out or is wrong,
the team cleanup function _TeamDied() will be called.
*/
void
AppManager::_BigBrother()
{
status_t status;
BMessage ping('PING');
BMessage reply;
do {
if (!Lock())
break;
AppMap::iterator iterator = fMap.begin();
for (; iterator != fMap.end(); iterator++) {
reply.what = 0;
status = iterator->second.SendMessage(&ping, &reply, 5000000,
2000000);
if (status != B_OK || reply.what != 'PONG') {
team_id team = iterator->first;
Unlock();
_TeamDied(team);
continue;
}
}
Unlock();
status = acquire_sem_etc(fQuit, 1, B_RELATIVE_TIMEOUT, 2000000);
} while (status == B_TIMED_OUT || status == B_INTERRUPTED);
}
+34 -31
View File
@@ -1,44 +1,47 @@
/*
/*
* Copyright 2002, Marcus Overhagen. All rights reserved.
* Distributed under the terms of the MIT License.
*/
#ifndef __APP_MANAGER_H
#define __APP_MANAGER_H
#ifndef APP_MANAGER_H
#define APP_MANAGER_H
#include "TMap.h"
class AppManager
{
#include <map>
#include <Locker.h>
#include <Messenger.h>
class AppManager : BLocker {
public:
AppManager();
~AppManager();
AppManager();
~AppManager();
status_t RegisterTeam(team_id, BMessenger);
status_t UnregisterTeam(team_id);
bool HasTeam(team_id);
status_t RegisterTeam(team_id team,
const BMessenger& messenger);
status_t UnregisterTeam(team_id team);
bool HasTeam(team_id team);
team_id AddonServerTeam();
status_t SendMessage(team_id team, BMessage *msg);
void Dump();
private:
void CleanupTeam(team_id);
void TeamDied(team_id team);
static int32 bigbrother(void *self);
void BigBrother();
team_id AddonServerTeam();
status_t SendMessage(team_id team, BMessage* message);
void Dump();
private:
thread_id fBigBrother;
sem_id fQuit;
void _CleanupTeam(team_id team);
void _TeamDied(team_id team);
struct App {
team_id team;
BMessenger messenger;
};
Map<team_id, App> * fAppMap;
BLocker *fLocker;
static status_t _BigBrotherEntry(void* self);
void _BigBrother();
private:
typedef std::map<team_id, BMessenger> AppMap;
AppMap fMap;
thread_id fBigBrother;
sem_id fQuit;
};
#endif // __APP_MANAGER_H
#endif // APP_MANAGER_H