Replace synchronization semaphore with async messages

* Remove SyncToServices, I will probably readd it in future
but this time using a local synchronization service more than
relying on the media_server to release the semaphore.
* Due to some discussions today in mailing list I decided
to step back and retry the initial way to notify media rosters
about media services status. It is woking by using two different
notifications for reconnecting to the media_server and notifying
the local subscribers.
* This speed up the media services restart.
* Sorry for the noise and very thanks for reviewing my code to
everyone.
This commit is contained in:
Dario Casalinuovo
2016-04-05 00:41:20 +02:00
parent 16732ae7a4
commit 11c7bd86e2
8 changed files with 44 additions and 69 deletions
-4
View File
@@ -44,10 +44,6 @@ public:
// Check if the media services are running.
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);
status_t GetAudioInput(media_node* _node);
+2 -1
View File
@@ -30,6 +30,8 @@ enum {
// sent by the rescan thread
MEDIA_SERVER_RESCAN_COMPLETED,
// sent to rosters when rescan is completed
MEDIA_SERVER_ALIVE,
// media add-on server
MEDIA_ADD_ON_SERVER_PLAY_MEDIA = '_TRU'
@@ -373,7 +375,6 @@ 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 {
+26 -45
View File
@@ -107,7 +107,6 @@ 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 {
@@ -3345,27 +3344,6 @@ 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)
@@ -3465,34 +3443,12 @@ BMediaRoster::MessageReceived(BMessage* message)
TRACE("BMediaRoster::MessageReceived media services are going up.");
// 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
// ready to run and we avoid sleeping.
snooze(2000000);
// Restore our friendship with the media servers
// Wait for media services to wake up and restore our friendship
if (MediaRosterEx(this)->BuildConnections() != B_OK) {
TRACE("BMediaRoster::MessageReceived can't reconnect"
"to media_server.");
}
for (int32 i = 0; i < sNotificationList.CountItems(); i++) {
RosterNotification* current;
if (sNotificationList.Get(i, &current) != true)
return;
if (current->what == B_MEDIA_SERVER_STARTED) {
if (current->messenger.SendMessage(
B_MEDIA_SERVER_STARTED) != B_OK) {
if(!current->messenger.IsValid())
sNotificationList.Remove(i);
}
}
}
}
return;
}
@@ -3527,6 +3483,31 @@ BMediaRoster::MessageReceived(BMessage* message)
return;
}
case MEDIA_SERVER_ALIVE:
{
if (!BMediaRoster::IsRunning())
return;
sServerIsUp = true;
TRACE("BMediaRoster::MessageReceived media services are"
" finally up.");
// Send the notification to our subscribers
for (int32 i = 0; i < sNotificationList.CountItems(); i++) {
RosterNotification* current;
if (sNotificationList.Get(i, &current) != true)
return;
if (current->what == B_MEDIA_SERVER_STARTED) {
if (current->messenger.SendMessage(
B_MEDIA_SERVER_STARTED) != B_OK) {
if(!current->messenger.IsValid())
sNotificationList.Remove(i);
}
}
}
}
case NODE_FINAL_RELEASE:
{
// This function is called by a BMediaNode to delete
+7 -9
View File
@@ -50,14 +50,11 @@ AppManager::AppManager()
:
BLocker("media app manager")
{
fGlobalSynchro = create_sem(0, "media server global synchro");
}
AppManager::~AppManager()
{
if (fGlobalSynchro != -1)
delete_sem(fGlobalSynchro);
}
@@ -70,8 +67,7 @@ AppManager::HasTeam(team_id team)
status_t
AppManager::RegisterTeam(team_id team, const BMessenger& messenger,
sem_id* sync)
AppManager::RegisterTeam(team_id team, const BMessenger& messenger)
{
BAutolock lock(this);
@@ -88,8 +84,6 @@ AppManager::RegisterTeam(team_id team, const BMessenger& messenger,
return B_NO_MEMORY;
}
*sync = fGlobalSynchro;
return B_OK;
}
@@ -157,9 +151,13 @@ AppManager::Dump()
void
AppManager::UnlockGlobalSynchro()
AppManager::NotifyRosters()
{
delete_sem(fGlobalSynchro);
BAutolock lock(this);
AppMap::iterator iterator = fMap.begin();
for (; iterator != fMap.end(); iterator++)
iterator->second.SendMessage(MEDIA_SERVER_ALIVE);
}
+2 -3
View File
@@ -18,7 +18,7 @@ public:
~AppManager();
status_t RegisterTeam(team_id team,
const BMessenger& messenger, sem_id* sync);
const BMessenger& messenger);
status_t UnregisterTeam(team_id team);
bool HasTeam(team_id team);
@@ -28,7 +28,7 @@ public:
void Dump();
void UnlockGlobalSynchro();
void NotifyRosters();
private:
void _CleanupTeam(team_id team);
@@ -37,7 +37,6 @@ private:
typedef std::map<team_id, BMessenger> AppMap;
AppMap fMap;
sem_id fGlobalSynchro;
};
+3 -3
View File
@@ -413,9 +413,6 @@ 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();
@@ -423,6 +420,9 @@ DefaultManager::_RescanThread()
fRescanThread = -1;
BMessage msg(MEDIA_SERVER_RESCAN_COMPLETED);
be_app->PostMessage(&msg);
TRACE("DefaultManager::_RescanThread() leave\n");
}
+1 -1
View File
@@ -2,7 +2,7 @@ SubDir HAIKU_TOP src servers media ;
SetSubDirSupportedPlatformsBeOSCompatible ;
UsePrivateHeaders media shared storage app ;
UsePrivateHeaders app media shared storage ;
UsePrivateSystemHeaders ;
AddResources media_server : media_server.rdef ;
+3 -3
View File
@@ -37,13 +37,13 @@ char __dont_remove_copyright_from_binary[] = "Copyright (c) 2002, 2003 "
#include <string.h>
#include <Alert.h>
#include <Server.h>
#include <Autolock.h>
#include <Directory.h>
#include <Roster.h>
#include <MediaDefs.h>
#include <MediaFormats.h>
#include <Messenger.h>
#include <Server.h>
#include <syscalls.h>
@@ -307,7 +307,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, &reply.global_synchro);
request.messenger);
request.SendReply(status, &reply, sizeof(reply));
break;
}
@@ -942,7 +942,7 @@ ServerApp::MessageReceived(BMessage* msg)
case MEDIA_SERVER_RESCAN_COMPLETED:
{
gAppManager->UnlockGlobalSynchro();
gAppManager->NotifyRosters();
progress_startup(100, NULL, NULL);
break;
}