* 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:
+109
-101
@@ -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();
|
Lock();
|
||||||
is_removed = fAppMap->Remove(team);
|
bool isRemoved = fMap.erase(team) != 0;
|
||||||
fLocker->Unlock();
|
Unlock();
|
||||||
|
|
||||||
CleanupTeam(team);
|
_CleanupTeam(team);
|
||||||
|
|
||||||
return is_removed ? B_OK : B_ERROR;
|
return isRemoved ? B_OK : B_ERROR;
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
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);
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
fLocker->Unlock();
|
printf("AppManager: list end\n");
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,43 +2,46 @@
|
|||||||
* 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:
|
private:
|
||||||
void CleanupTeam(team_id);
|
void _CleanupTeam(team_id team);
|
||||||
void TeamDied(team_id team);
|
void _TeamDied(team_id team);
|
||||||
static int32 bigbrother(void *self);
|
|
||||||
void BigBrother();
|
static status_t _BigBrotherEntry(void* self);
|
||||||
|
void _BigBrother();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
typedef std::map<team_id, BMessenger> AppMap;
|
||||||
|
|
||||||
|
AppMap fMap;
|
||||||
thread_id fBigBrother;
|
thread_id fBigBrother;
|
||||||
sem_id fQuit;
|
sem_id fQuit;
|
||||||
|
|
||||||
struct App {
|
|
||||||
team_id team;
|
|
||||||
BMessenger messenger;
|
|
||||||
};
|
|
||||||
Map<team_id, App> * fAppMap;
|
|
||||||
BLocker *fLocker;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // __APP_MANAGER_H
|
|
||||||
|
#endif // APP_MANAGER_H
|
||||||
|
|||||||
Reference in New Issue
Block a user