Skip to content

Commit

Permalink
Introduce functionality for syncing with the media services
Browse files Browse the repository at this point in the history
* 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.
  • Loading branch information
Numerio committed Apr 3, 2016
1 parent 866084f commit 53c3fa5
Show file tree
Hide file tree
Showing 7 changed files with 64 additions and 5 deletions.
6 changes: 5 additions & 1 deletion headers/os/media/MediaRoster.h
Expand Up @@ -42,7 +42,11 @@ class BMediaRoster : public BLooper {
// 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);
Expand Down
4 changes: 4 additions & 0 deletions headers/private/media/ServerInterface.h
Expand Up @@ -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'
};
Expand Down Expand Up @@ -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 {
Expand Down
24 changes: 24 additions & 0 deletions src/kits/media/MediaRoster.cpp
Expand Up @@ -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 {
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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
Expand Down
15 changes: 14 additions & 1 deletion src/servers/media/AppManager.cpp
Expand Up @@ -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);
}


Expand All @@ -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);

Expand All @@ -84,6 +88,8 @@ AppManager::RegisterTeam(team_id team, const BMessenger& messenger)
return B_NO_MEMORY;
}

*sync = fGlobalSynchro;

return B_OK;
}

Expand Down Expand Up @@ -150,6 +156,13 @@ AppManager::Dump()
}


void
AppManager::UnlockGlobalSynchro()
{
delete_sem(fGlobalSynchro);
}


void
AppManager::_CleanupTeam(team_id team)
{
Expand Down
5 changes: 4 additions & 1 deletion src/servers/media/AppManager.h
Expand Up @@ -18,7 +18,7 @@ class AppManager : BLocker {
~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);

Expand All @@ -28,13 +28,16 @@ class AppManager : BLocker {

void Dump();

void UnlockGlobalSynchro();

private:
void _CleanupTeam(team_id team);

private:
typedef std::map<team_id, BMessenger> AppMap;

AppMap fMap;
sem_id fGlobalSynchro;
};


Expand Down
7 changes: 6 additions & 1 deletion src/servers/media/DefaultManager.cpp
Expand Up @@ -16,9 +16,11 @@
#include <TimeSource.h>
#include <string.h>

#include "debug.h"
#include "DormantNodeManager.h"
#include "media_server.h"
#include "NodeManager.h"
#include "debug.h"


/* no locking used in this file, we assume that the caller (NodeManager) does it.
*/
Expand Down Expand Up @@ -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();
Expand Down
8 changes: 7 additions & 1 deletion src/servers/media/media_server.cpp
Expand Up @@ -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;
}
Expand Down Expand Up @@ -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;
Expand Down

0 comments on commit 53c3fa5

Please sign in to comment.