[haiku-commits] haiku: hrev49893 - src/kits/media src/kits/app headers/os/app

  • From: b.vitruvio@xxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Sat, 28 Nov 2015 17:02:29 +0100 (CET)

hrev49893 adds 4 changesets to branch 'master'
old head: 893e3de866127920293f3de1b4d7968717468045
new head: 6423f87f9e6016db30019028470fdc46f0771fbb
overview:
http://cgit.haiku-os.org/haiku/log/?qt=range&q=6423f87f9e60+%5E893e3de86612

----------------------------------------------------------------------------

05962bb1e1a7: Add a way to register loopers for quit

* BApplication can now take the job to quit a BLooper at
the application quit. It's rejecting requests from windows too.
* BMediaRoster is using now this service in conjunction with the
MediaRosterUndertaker.
* The BeBook specify that we should have a valid BApplication
before to instantiate the BMediaRoster. While in theory we should
add a debugger call when this situation happens, in pratice this
might lead to more problems. For example libraries might use the
media_kit and create a BApplication object, but they aren't
applications, this is a design problem. So I decided to replace it
with a TRACE call for the moment.

67060664c9b1: Allow BMediaRoster to log local nodes

* BMediaRoster is now capable to know which nodes are
instantiated in this team. This is also a first step to make
them survive after media_server crashes.
* A control at BMediaRoster::Quit can notify if all nodes
were correctly released. Ideally at this point the local nodes
list should be empty.

d98b8c7c5993: BufferCache: More strict validity checks

* This add a debugger call if the BBuffer id is
mismatched at object creation.

6423f87f9e60: BMediaRoster: Reference count polishment

* BMediaNode is registering it's presence to the roster.
* Only addons needs their configuration to be saved.

[ Dario Casalinuovo <b.vitruvio@xxxxxxxxx> ]

----------------------------------------------------------------------------

6 files changed, 153 insertions(+), 25 deletions(-)
headers/os/app/Application.h | 5 ++
headers/private/media/MediaRosterEx.h | 3 ++
src/kits/app/Application.cpp | 42 +++++++++++++++
src/kits/media/BufferCache.cpp | 6 ++-
src/kits/media/MediaNode.cpp | 32 ++++++++---
src/kits/media/MediaRoster.cpp | 90 +++++++++++++++++++++++++------

############################################################################

Commit: 05962bb1e1a76751f73f9c63dc0cc8c0427dc819
URL: http://cgit.haiku-os.org/haiku/commit/?id=05962bb1e1a7
Author: Dario Casalinuovo <b.vitruvio@xxxxxxxxx>
Date: Sat Nov 28 15:17:34 2015 UTC

Add a way to register loopers for quit

* BApplication can now take the job to quit a BLooper at
the application quit. It's rejecting requests from windows too.
* BMediaRoster is using now this service in conjunction with the
MediaRosterUndertaker.
* The BeBook specify that we should have a valid BApplication
before to instantiate the BMediaRoster. While in theory we should
add a debugger call when this situation happens, in pratice this
might lead to more problems. For example libraries might use the
media_kit and create a BApplication object, but they aren't
applications, this is a design problem. So I decided to replace it
with a TRACE call for the moment.

----------------------------------------------------------------------------

diff --git a/headers/os/app/Application.h b/headers/os/app/Application.h
index ef7881d..13a0982 100644
--- a/headers/os/app/Application.h
+++ b/headers/os/app/Application.h
@@ -85,6 +85,11 @@ public:

BHandler* handler);
void SetPulseRate(bigtime_t
rate);

+ // Register a BLooper to be quit before the BApplication
+ // object is destroyed.
+ status_t RegisterLooper(BLooper*
looper);
+ status_t
UnregisterLooper(BLooper* looper);
+
// More scripting
virtual status_t GetSupportedSuites(BMessage*
data);

diff --git a/src/kits/app/Application.cpp b/src/kits/app/Application.cpp
index cda2c6d..c1c3f33 100644
--- a/src/kits/app/Application.cpp
+++ b/src/kits/app/Application.cpp
@@ -61,6 +61,7 @@ BMessenger be_app_messenger;

pthread_once_t sAppResourcesInitOnce = PTHREAD_ONCE_INIT;
BResources* BApplication::sAppResources = NULL;
+BObjectList<BLooper> sOnQuitLooperList;


enum {
@@ -306,6 +307,13 @@ BApplication::~BApplication()
// tell all loopers(usually windows) to quit. Also, wait for them.
_QuitAllWindows(true);

+ // quit registered loopers
+ for (int32 i = 0; i < sOnQuitLooperList.CountItems(); i++) {
+ BLooper* looper = sOnQuitLooperList.ItemAt(i);
+ if (looper->Lock())
+ looper->Quit();
+ }
+
// unregister from the roster
BRoster::Private().RemoveApp(Team());

@@ -960,6 +968,40 @@ BApplication::LooperAt(int32 index) const
}


+status_t
+BApplication::RegisterLooper(BLooper* looper)
+{
+ BWindow* window = dynamic_cast<BWindow*>(looper);
+ if (window != NULL)
+ return B_BAD_VALUE;
+
+ if (sOnQuitLooperList.HasItem(looper))
+ return B_ERROR;
+
+ if (sOnQuitLooperList.AddItem(looper) != true)
+ return B_ERROR;
+
+ return B_OK;
+}
+
+
+status_t
+BApplication::UnregisterLooper(BLooper* looper)
+{
+ BWindow* window = dynamic_cast<BWindow*>(looper);
+ if (window != NULL)
+ return B_BAD_VALUE;
+
+ if (!sOnQuitLooperList.HasItem(looper))
+ return B_ERROR;
+
+ if (sOnQuitLooperList.RemoveItem(looper) != true)
+ return B_ERROR;
+
+ return B_OK;
+}
+
+
bool
BApplication::IsLaunching() const
{
diff --git a/src/kits/media/MediaRoster.cpp b/src/kits/media/MediaRoster.cpp
index 6351302..12a948a 100644
--- a/src/kits/media/MediaRoster.cpp
+++ b/src/kits/media/MediaRoster.cpp
@@ -42,8 +42,7 @@ char __dont_remove_copyright_from_binary[] = "Copyright (c)
2002-2006 Marcus "

#include <MediaRoster.h>

-#include <new>
-
+#include <Application.h>
#include <Autolock.h>
#include <BufferConsumer.h>
#include <BufferProducer.h>
@@ -58,8 +57,9 @@ char __dont_remove_copyright_from_binary[] = "Copyright (c)
2002-2006 Marcus "
#include <String.h>
#include <TimeSource.h>

-#include <AppMisc.h>
+#include <new>

+#include <AppMisc.h>
#include <DataExchange.h>
#include <debug.h>
#include <DormantNodeManager.h>
@@ -82,6 +82,7 @@ struct RosterNotification {
int32 what;
};

+
static bool sServerIsUp = false;
static List<RosterNotification> sNotificationList;
static BLocker sInitLocker("BMediaRoster::Roster locker");
@@ -94,6 +95,10 @@ public:
BAutolock _(sInitLocker);
if (BMediaRoster::CurrentRoster() != NULL
&& BMediaRoster::CurrentRoster()->Lock()) {
+
+ if (be_app != NULL)
+
be_app->UnregisterLooper(BMediaRoster::CurrentRoster());
+
BMediaRoster::CurrentRoster()->Quit();
}
}
@@ -2221,6 +2226,9 @@ BMediaRoster::Roster(status_t* out_error)
{
BAutolock lock(sInitLocker);

+ if (be_app == NULL)
+ TRACE("Warning! You should have a valid BApplication.");
+
if (!lock.IsLocked())
return NULL;

@@ -2240,8 +2248,11 @@ BMediaRoster::Roster(status_t* out_error)
}
if (out_error)
*out_error = err;
+ } else if (be_app != NULL) {
+ be_app->RegisterLooper(sDefaultInstance);
}
}
+
return sDefaultInstance;
}


############################################################################

Commit: 67060664c9b136574a9272dc34e209c9d5f99ba4
URL: http://cgit.haiku-os.org/haiku/commit/?id=67060664c9b1
Author: Dario Casalinuovo <b.vitruvio@xxxxxxxxx>
Date: Sat Nov 28 15:28:10 2015 UTC

Allow BMediaRoster to log local nodes

* BMediaRoster is now capable to know which nodes are
instantiated in this team. This is also a first step to make
them survive after media_server crashes.
* A control at BMediaRoster::Quit can notify if all nodes
were correctly released. Ideally at this point the local nodes
list should be empty.

----------------------------------------------------------------------------

diff --git a/headers/private/media/MediaRosterEx.h
b/headers/private/media/MediaRosterEx.h
index 74bec12..da50ddc 100644
--- a/headers/private/media/MediaRosterEx.h
+++ b/headers/private/media/MediaRosterEx.h
@@ -92,6 +92,9 @@ public:

status_t BuildConnections();

+ void RegisterLocalNode(BMediaNode*
node);
+ void UnregisterLocalNode(BMediaNode*
node);
+
private:
friend class BMediaRoster;
};
diff --git a/src/kits/media/MediaRoster.cpp b/src/kits/media/MediaRoster.cpp
index 12a948a..2577719 100644
--- a/src/kits/media/MediaRoster.cpp
+++ b/src/kits/media/MediaRoster.cpp
@@ -83,9 +83,30 @@ struct RosterNotification {
};


+struct LocalNode {
+ LocalNode(BMediaNode* local_node)
+ :
+ node(local_node) {}
+
+ LocalNode()
+ :
+ node(NULL) {}
+
+ bool operator==(const LocalNode& a)
+ {
+ if (a.node == this->node)
+ return true;
+ return false;
+ }
+
+ BMediaNode* node;
+};
+
+
static bool sServerIsUp = false;
static List<RosterNotification> sNotificationList;
static BLocker sInitLocker("BMediaRoster::Roster locker");
+static List<LocalNode> sRegisteredNodes;


class MediaRosterUndertaker {
@@ -96,6 +117,18 @@ public:
if (BMediaRoster::CurrentRoster() != NULL
&& BMediaRoster::CurrentRoster()->Lock()) {

+ // Detect any forgotten node
+ if (sRegisteredNodes.CountItems() > 0) {
+ for (int32 i = 0; i <
sRegisteredNodes.CountItems(); i++) {
+ LocalNode* node = NULL;
+ sRegisteredNodes.Get(i, &node);
+ if (node != NULL) {
+ ERROR("BMediaRoster: Node with
ID %" B_PRId32
+ " was not released
correctly\n", node->node->ID());
+ }
+ }
+ }
+
if (be_app != NULL)

be_app->UnregisterLooper(BMediaRoster::CurrentRoster());

@@ -181,6 +214,22 @@ BMediaRosterEx::~BMediaRosterEx()
}


+void
+BMediaRosterEx::RegisterLocalNode(BMediaNode* node)
+{
+ sRegisteredNodes.Insert(LocalNode(node));
+}
+
+
+void
+BMediaRosterEx::UnregisterLocalNode(BMediaNode* node)
+{
+ int32 index = sRegisteredNodes.Find(LocalNode(node));
+ if (index != -1)
+ sRegisteredNodes.Remove(index);
+}
+
+
status_t
BMediaRosterEx::SaveNodeConfiguration(BMediaNode* node)
{

############################################################################

Commit: d98b8c7c59938496a637765d75ce3585bb30fa68
URL: http://cgit.haiku-os.org/haiku/commit/?id=d98b8c7c5993
Author: Dario Casalinuovo <b.vitruvio@xxxxxxxxx>
Date: Thu Nov 19 17:49:01 2015 UTC

BufferCache: More strict validity checks

* This add a debugger call if the BBuffer id is
mismatched at object creation.

----------------------------------------------------------------------------

diff --git a/src/kits/media/BufferCache.cpp b/src/kits/media/BufferCache.cpp
index 5548e34..02ea721 100644
--- a/src/kits/media/BufferCache.cpp
+++ b/src/kits/media/BufferCache.cpp
@@ -45,11 +45,15 @@ BufferCache::GetBuffer(media_buffer_id id)
buffer_clone_info info;
info.buffer = id;
BBuffer* buffer = new(std::nothrow) BBuffer(info);
- if (buffer == NULL || buffer->Data() == NULL) {
+ if (buffer == NULL || buffer->ID() <= 0
+ || buffer->Data() == NULL) {
delete buffer;
return NULL;
}

+ if (buffer->ID() != id)
+ debugger("BufferCache::GetBuffer: IDs mismatch");
+
try {
fMap.insert(std::make_pair(id, buffer));
} catch (std::bad_alloc& exception) {

############################################################################

Revision: hrev49893
Commit: 6423f87f9e6016db30019028470fdc46f0771fbb
URL: http://cgit.haiku-os.org/haiku/commit/?id=6423f87f9e60
Author: Dario Casalinuovo <b.vitruvio@xxxxxxxxx>
Date: Thu Nov 19 17:50:38 2015 UTC

BMediaRoster: Reference count polishment

* BMediaNode is registering it's presence to the roster.
* Only addons needs their configuration to be saved.

----------------------------------------------------------------------------

diff --git a/src/kits/media/MediaNode.cpp b/src/kits/media/MediaNode.cpp
index c7b5f21..5f2ab4f 100644
--- a/src/kits/media/MediaNode.cpp
+++ b/src/kits/media/MediaNode.cpp
@@ -151,7 +151,12 @@ BMediaNode*
BMediaNode::Acquire()
{
CALLED();
- atomic_add(&fRefCount,1);
+ if (atomic_add(&fRefCount,1) == 0) {
+ status_t status = B_ERROR;
+ BMediaRoster* roster = BMediaRoster::Roster(&status);
+ if (roster != NULL && status == B_OK)
+ MediaRosterEx(roster)->RegisterLocalNode(this);
+ }
return this;
}

@@ -161,13 +166,26 @@ BMediaNode::Release()
{
CALLED();
if (atomic_add(&fRefCount, -1) == 1) {
- TRACE("BMediaNode::Release() saving node %ld configuration\n",
fNodeID);
-
MediaRosterEx(BMediaRoster::Roster())->SaveNodeConfiguration(this);
- if (DeleteHook(this) != B_OK) {
- ERROR("BMediaNode::Release(): DeleteHook failed\n");
- return Acquire();
+ status_t status = B_ERROR;
+ BMediaRoster* roster = BMediaRoster::Roster(&status);
+ if (roster != NULL && status == B_OK) {
+ MediaRosterEx(roster)->UnregisterLocalNode(this);
+
+ // Only addons needs the configuration to be saved.
+ int32 id;
+ if (AddOn(&id) != NULL) {
+ TRACE("BMediaNode::Release() saving node %ld"
+ " configuration\n", fNodeID);
+
MediaRosterEx(roster)->SaveNodeConfiguration(this);
+ }
+
+ if (DeleteHook(this) != B_OK) {
+ ERROR("BMediaNode::Release(): DeleteHook
failed\n");
+ return Acquire();
+ }
+ return NULL;
}
- return NULL;
+ TRACE("BMediaRoster::Release() the media roster is NULL!");
}
return this;
}
diff --git a/src/kits/media/MediaRoster.cpp b/src/kits/media/MediaRoster.cpp
index 2577719..35c1ac4 100644
--- a/src/kits/media/MediaRoster.cpp
+++ b/src/kits/media/MediaRoster.cpp
@@ -3530,23 +3530,19 @@ BMediaRoster::MessageReceived(BMessage* message)

case NODE_FINAL_RELEASE:
{
- // this function is called by a BMediaNode to delete
+ // This function is called by a BMediaNode to delete
// itself, as this needs to be done from another thread
// context, it is done here.
- // TODO: If a node is released using
BMediaRoster::ReleaseNode()
- // TODO: instead of using BMediaNode::Release() /
BMediaNode::Acquire()
- // TODO: fRefCount of the BMediaNode will not be
correct.

- BMediaNode *node;
- message->FindPointer("node", reinterpret_cast<void
**>(&node));
-
- TRACE("BMediaRoster::MessageReceived NODE_FINAL_RELEASE
saving "
- "node %" B_PRId32 " configuration\n",
node->ID());
-
MediaRosterEx(BMediaRoster::Roster())->SaveNodeConfiguration(node);
-
- TRACE("BMediaRoster::MessageReceived NODE_FINAL_RELEASE
releasing "
- "node %" B_PRId32 "\n", node->ID());
- node->DeleteHook(node); // we don't call Release(), see
above!
+ BMediaNode* node = NULL;
+ status_t err = message->FindPointer("node",
+ reinterpret_cast<void **>(&node));
+ if (err == B_OK && node != NULL)
+ node->Release();
+ else {
+ TRACE("BMediaRoster::MessageReceived: CRITICAL!
received"
+ "a release request but the node can't
be found.");
+ }
return;
}



Other related posts:

  • » [haiku-commits] haiku: hrev49893 - src/kits/media src/kits/app headers/os/app - b . vitruvio