Introduce functionality for syncing with the media services
* The global synchro semaphore is provided with the purpose of being used to avoid threads lock up when the media_server is in an undefined state. There's still room for improvements. * BMediaRoster::SyncToServices lock up on a semaphore until the multi_audio correctly connected to the mixer.
This commit is contained in:
@@ -42,7 +42,11 @@ public:
|
||||
// same time.
|
||||
|
||||
// Check if the media services are running.
|
||||
static bool IsRunning();
|
||||
static bool IsRunning();
|
||||
|
||||
// This functions blocks until the media services are available,
|
||||
// don't abuse of it.
|
||||
static status_t SyncToServices(bigtime_t timeout = -1);
|
||||
|
||||
// Getting common instances of system nodes:
|
||||
status_t GetVideoInput(media_node* _node);
|
||||
|
||||
@@ -28,6 +28,9 @@ enum {
|
||||
// add_system_beep_event()
|
||||
MEDIA_SERVER_ADD_SYSTEM_BEEP_EVENT,
|
||||
|
||||
// sent by the rescan thread
|
||||
MEDIA_SERVER_RESCAN_COMPLETED,
|
||||
|
||||
// media add-on server
|
||||
MEDIA_ADD_ON_SERVER_PLAY_MEDIA = '_TRU'
|
||||
};
|
||||
@@ -370,6 +373,7 @@ struct server_register_app_request : request_data {
|
||||
};
|
||||
|
||||
struct server_register_app_reply : reply_data {
|
||||
sem_id global_synchro;
|
||||
};
|
||||
|
||||
struct server_unregister_app_request : request_data {
|
||||
|
||||
@@ -107,6 +107,7 @@ static bool sServerIsUp = false;
|
||||
static List<RosterNotification> sNotificationList;
|
||||
static BLocker sInitLocker("BMediaRoster::Roster locker");
|
||||
static List<LocalNode> sRegisteredNodes;
|
||||
static sem_id sGlobalSynchro = -1;
|
||||
|
||||
|
||||
class MediaRosterUndertaker {
|
||||
@@ -3344,6 +3345,27 @@ BMediaRoster::IsRunning()
|
||||
}
|
||||
|
||||
|
||||
status_t
|
||||
BMediaRoster::SyncToServices(bigtime_t timeout)
|
||||
{
|
||||
if (!IsRunning())
|
||||
return B_ERROR;
|
||||
|
||||
TRACE("BMediaRoster::SyncToServer: Syncing to the media server");
|
||||
|
||||
// This sem is valid only when the server started
|
||||
// but it's not ready to supply the services.
|
||||
if (sGlobalSynchro > -1)
|
||||
acquire_sem_etc(sGlobalSynchro, 1, B_RELATIVE_TIMEOUT, timeout);
|
||||
|
||||
// TODO: Ideally this function should take into account
|
||||
// the startup latencies of the system nodes and sleep
|
||||
// for the resulting sum.
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
|
||||
ssize_t
|
||||
BMediaRoster::AudioBufferSizeFor(int32 channelCount, uint32 sampleFormat,
|
||||
float frameRate, bus_type busKind)
|
||||
@@ -3445,7 +3467,9 @@ BMediaRoster::MessageReceived(BMessage* message)
|
||||
|
||||
// Send the notification to our subscribers
|
||||
if (BMediaRoster::IsRunning()) {
|
||||
SyncToServices();
|
||||
sServerIsUp = true;
|
||||
sGlobalSynchro = -1;
|
||||
// Wait for media services to wake up
|
||||
// TODO: This should be solved so that the server
|
||||
// have a way to notify us when the system is really
|
||||
|
||||
@@ -50,11 +50,14 @@ AppManager::AppManager()
|
||||
:
|
||||
BLocker("media app manager")
|
||||
{
|
||||
fGlobalSynchro = create_sem(0, "media server global synchro");
|
||||
}
|
||||
|
||||
|
||||
AppManager::~AppManager()
|
||||
{
|
||||
if (fGlobalSynchro != -1)
|
||||
delete_sem(fGlobalSynchro);
|
||||
}
|
||||
|
||||
|
||||
@@ -67,7 +70,8 @@ AppManager::HasTeam(team_id team)
|
||||
|
||||
|
||||
status_t
|
||||
AppManager::RegisterTeam(team_id team, const BMessenger& messenger)
|
||||
AppManager::RegisterTeam(team_id team, const BMessenger& messenger,
|
||||
sem_id* sync)
|
||||
{
|
||||
BAutolock lock(this);
|
||||
|
||||
@@ -84,6 +88,8 @@ AppManager::RegisterTeam(team_id team, const BMessenger& messenger)
|
||||
return B_NO_MEMORY;
|
||||
}
|
||||
|
||||
*sync = fGlobalSynchro;
|
||||
|
||||
return B_OK;
|
||||
}
|
||||
|
||||
@@ -150,6 +156,13 @@ AppManager::Dump()
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AppManager::UnlockGlobalSynchro()
|
||||
{
|
||||
delete_sem(fGlobalSynchro);
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
AppManager::_CleanupTeam(team_id team)
|
||||
{
|
||||
|
||||
@@ -18,7 +18,7 @@ public:
|
||||
~AppManager();
|
||||
|
||||
status_t RegisterTeam(team_id team,
|
||||
const BMessenger& messenger);
|
||||
const BMessenger& messenger, sem_id* sync);
|
||||
status_t UnregisterTeam(team_id team);
|
||||
bool HasTeam(team_id team);
|
||||
|
||||
@@ -28,6 +28,8 @@ public:
|
||||
|
||||
void Dump();
|
||||
|
||||
void UnlockGlobalSynchro();
|
||||
|
||||
private:
|
||||
void _CleanupTeam(team_id team);
|
||||
|
||||
@@ -35,6 +37,7 @@ private:
|
||||
typedef std::map<team_id, BMessenger> AppMap;
|
||||
|
||||
AppMap fMap;
|
||||
sem_id fGlobalSynchro;
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -16,9 +16,11 @@
|
||||
#include <TimeSource.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "DormantNodeManager.h"
|
||||
#include "NodeManager.h"
|
||||
#include "debug.h"
|
||||
#include "DormantNodeManager.h"
|
||||
#include "media_server.h"
|
||||
#include "NodeManager.h"
|
||||
|
||||
|
||||
/* no locking used in this file, we assume that the caller (NodeManager) does it.
|
||||
*/
|
||||
@@ -411,6 +413,9 @@ DefaultManager::_RescanThread()
|
||||
add_on_server_rescan_finished_notify_command cmd;
|
||||
SendToAddOnServer(ADD_ON_SERVER_RESCAN_FINISHED_NOTIFY, &cmd,
|
||||
sizeof(cmd));
|
||||
|
||||
BMessage msg(MEDIA_SERVER_RESCAN_COMPLETED);
|
||||
be_app->PostMessage(&msg);
|
||||
}
|
||||
|
||||
locker.Lock();
|
||||
|
||||
@@ -305,7 +305,7 @@ ServerApp::_HandleMessage(int32 code, const void* data, size_t size)
|
||||
server_register_app_reply reply;
|
||||
|
||||
status_t status = gAppManager->RegisterTeam(request.team,
|
||||
request.messenger);
|
||||
request.messenger, &reply.global_synchro);
|
||||
request.SendReply(status, &reply, sizeof(reply));
|
||||
break;
|
||||
}
|
||||
@@ -938,6 +938,12 @@ ServerApp::MessageReceived(BMessage* msg)
|
||||
gMediaFilesManager->HandleAddSystemBeepEvent(msg);
|
||||
break;
|
||||
|
||||
case MEDIA_SERVER_RESCAN_COMPLETED:
|
||||
{
|
||||
gAppManager->UnlockGlobalSynchro();
|
||||
break;
|
||||
}
|
||||
|
||||
case B_SOME_APP_QUIT:
|
||||
{
|
||||
BString mimeSig;
|
||||
|
||||
Reference in New Issue
Block a user