* 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 "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 "BufferManager.h"
#include "NotificationManager.h"
#include "media_server.h" #include "media_server.h"
#include "NodeManager.h"
#include "NotificationManager.h"
AppManager::AppManager() 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"); 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); resume_thread(fBigBrother);
} }
AppManager::~AppManager() AppManager::~AppManager()
{ {
status_t err;
delete_sem(fQuit); delete_sem(fQuit);
wait_for_thread(fBigBrother, &err); wait_for_thread(fBigBrother, NULL);
delete fLocker;
delete fAppMap;
} }
bool bool
AppManager::HasTeam(team_id team) AppManager::HasTeam(team_id team)
{ {
BAutolock lock(fLocker); BAutolock lock(this);
return fAppMap->Has(team); return fMap.find(team) != fMap.end();
} }
status_t 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); TRACE("AppManager::RegisterTeam %ld\n", team);
if (HasTeam(team)) { if (HasTeam(team)) {
ERROR("AppManager::RegisterTeam: team %ld already registered\n", team); ERROR("AppManager::RegisterTeam: team %ld already registered\n", team);
return B_ERROR; return B_ERROR;
} }
App app;
app.team = team; try {
app.messenger = messenger; fMap.insert(std::make_pair(team, messenger));
return fAppMap->Insert(team, app) ? B_OK : B_ERROR; } catch (std::bad_alloc& exception) {
return B_NO_MEMORY;
}
return B_OK;
} }
status_t status_t
AppManager::UnregisterTeam(team_id team) AppManager::UnregisterTeam(team_id team)
{ {
bool is_removed;
TRACE("AppManager::UnregisterTeam %ld\n", team); 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 _CleanupTeam(team);
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);
}
return isRemoved ? B_OK : B_ERROR;
void
AppManager::TeamDied(team_id team)
{
CleanupTeam(team);
fLocker->Lock();
fAppMap->Remove(team);
fLocker->Unlock();
} }
@@ -135,55 +120,44 @@ AppManager::AddonServerTeam()
} }
//========================================================================= status_t
// The BigBrother thread send ping messages to the BMediaRoster of AppManager::SendMessage(team_id team, BMessage* message)
// 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)
{ {
static_cast<AppManager *>(self)->BigBrother(); BAutolock lock(this);
return 0;
AppMap::iterator found = fMap.find(team);
if (found == fMap.end())
return B_NAME_NOT_FOUND;
return found->second.SendMessage(message);
} }
void void
AppManager::BigBrother() AppManager::Dump()
{ {
status_t status; BAutolock lock(this);
BMessage msg('PING');
BMessage reply; printf("\n");
team_id team; printf("AppManager: list of applications follows:\n");
App *app;
do { app_info info;
if (!fLocker->Lock()) AppMap::iterator iterator = fMap.begin();
break; for (; iterator != fMap.end(); iterator++) {
for (fAppMap->Rewind(); fAppMap->GetNext(&app); ) { app_info info;
reply.what = 0; be_roster->GetRunningAppInfo(iterator->first, &info);
status = app->messenger.SendMessage(&msg, &reply, 5000000, 2000000); printf(" team %ld \"%s\", messenger %svalid\n", iterator->first,
if (status != B_OK || reply.what != 'PONG') { info.ref.name, iterator->second.IsValid() ? "" : "NOT ");
team = app->team; }
fLocker->Unlock();
TeamDied(team); printf("AppManager: list end\n");
continue;
}
}
fLocker->Unlock();
status = acquire_sem_etc(fQuit, 1, B_RELATIVE_TIMEOUT, 2000000);
} while (status == B_TIMED_OUT || status == B_INTERRUPTED);
} }
//=========================================================================
// The following functions must be called unlocked.
// They clean up after a crash, or start/terminate the media_addon_server.
//=========================================================================
void 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); TRACE("AppManager: cleaning up team %ld\n", team);
@@ -194,16 +168,50 @@ AppManager::CleanupTeam(team_id team)
void void
AppManager::Dump() AppManager::_TeamDied(team_id team)
{ {
BAutolock lock(fLocker); UnregisterTeam(team);
printf("\n"); }
printf("AppManager: list of applications follows:\n");
App *app;
app_info info; status_t
for (fAppMap->Rewind(); fAppMap->GetNext(&app); ) { AppManager::_BigBrotherEntry(void* self)
be_roster->GetRunningAppInfo(app->team, &info); {
printf(" team %ld \"%s\", messenger %svalid\n", app->team, info.ref.name, app->messenger.IsValid() ? "" : "NOT "); static_cast<AppManager*>(self)->_BigBrother();
} return 0;
printf("AppManager: list end\n"); }
/*! 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. * Copyright 2002, Marcus Overhagen. All rights reserved.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
*/ */
#ifndef __APP_MANAGER_H #ifndef APP_MANAGER_H
#define __APP_MANAGER_H #define APP_MANAGER_H
#include "TMap.h"
class AppManager #include <map>
{
#include <Locker.h>
#include <Messenger.h>
class AppManager : BLocker {
public: public:
AppManager(); AppManager();
~AppManager(); ~AppManager();
status_t RegisterTeam(team_id, BMessenger); status_t RegisterTeam(team_id team,
status_t UnregisterTeam(team_id); const BMessenger& messenger);
bool HasTeam(team_id); status_t UnregisterTeam(team_id team);
bool HasTeam(team_id team);
team_id AddonServerTeam(); team_id AddonServerTeam();
status_t SendMessage(team_id team, BMessage *msg); status_t SendMessage(team_id team, BMessage* message);
void Dump(); void Dump();
private:
void CleanupTeam(team_id);
void TeamDied(team_id team);
static int32 bigbrother(void *self);
void BigBrother();
private: private:
thread_id fBigBrother; void _CleanupTeam(team_id team);
sem_id fQuit; void _TeamDied(team_id team);
struct App { static status_t _BigBrotherEntry(void* self);
team_id team; void _BigBrother();
BMessenger messenger;
}; private:
Map<team_id, App> * fAppMap; typedef std::map<team_id, BMessenger> AppMap;
BLocker *fLocker;
AppMap fMap;
thread_id fBigBrother;
sem_id fQuit;
}; };
#endif // __APP_MANAGER_H
#endif // APP_MANAGER_H