* The SharedBufferList is now only cloned once in a team, no longer once for

each buffer, and once for each buffer group.
* Also, SharedBufferList::Get() now gets the area to clone from itself, if
  necessary, the caller no longer has to provide it.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@34502 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler 2009-12-05 11:52:01 +00:00
parent 69972fe0de
commit 2f9ed888a2
5 changed files with 61 additions and 45 deletions

View File

@ -16,7 +16,8 @@ namespace BPrivate {
class SharedBufferList { class SharedBufferList {
public: public:
static area_id Create(SharedBufferList** _list); static area_id Create(SharedBufferList** _list);
static SharedBufferList* Get(area_id area); static SharedBufferList* Get();
static void Invalidate();
void Put(); void Put();
void DeleteGroupAndPut(sem_id groupReclaimSem); void DeleteGroupAndPut(sem_id groupReclaimSem);

View File

@ -201,16 +201,7 @@ BBuffer::BBuffer(const buffer_clone_info& info)
if (info.area == 0 && info.buffer == 0) if (info.area == 0 && info.buffer == 0)
return; return;
// ask media_server to get the area_id of the shared buffer list fBufferList = BPrivate::SharedBufferList::Get();
server_get_shared_buffer_area_request areaRequest;
server_get_shared_buffer_area_reply areaReply;
if (QueryServer(SERVER_GET_SHARED_BUFFER_AREA, &areaRequest,
sizeof(areaRequest), &areaReply, sizeof(areaReply)) != B_OK) {
ERROR("BBuffer::BBuffer: SERVER_GET_SHARED_BUFFER_AREA failed\n");
return;
}
fBufferList = BPrivate::SharedBufferList::Get(areaReply.area);
if (fBufferList == NULL) { if (fBufferList == NULL) {
ERROR("BBuffer::BBuffer: _shared_buffer_list::Clone() failed\n"); ERROR("BBuffer::BBuffer: _shared_buffer_list::Clone() failed\n");
return; return;

View File

@ -393,18 +393,7 @@ BBufferGroup::_Init()
return fInitError; return fInitError;
} }
// ask media_server to get the area_id of the shared buffer list fBufferList = BPrivate::SharedBufferList::Get();
server_get_shared_buffer_area_request areaRequest;
server_get_shared_buffer_area_reply areaReply;
if (QueryServer(SERVER_GET_SHARED_BUFFER_AREA, &areaRequest,
sizeof(areaRequest), &areaReply, sizeof(areaReply)) != B_OK) {
ERROR("BBufferGroup::InitBufferGroup: SERVER_GET_SHARED_BUFFER_AREA "
"failed\n");
fInitError = B_ERROR;
return fInitError;
}
fBufferList = BPrivate::SharedBufferList::Get(areaReply.area);
if (fBufferList == NULL) { if (fBufferList == NULL) {
ERROR("BBufferGroup::InitBufferGroup: SharedBufferList::Get() " ERROR("BBufferGroup::InitBufferGroup: SharedBufferList::Get() "
"failed\n"); "failed\n");

View File

@ -57,16 +57,19 @@ char __dont_remove_copyright_from_binary[] = "Copyright (c) 2002-2006 Marcus "
#include <AppMisc.h> #include <AppMisc.h>
#include "debug.h" #include <debug.h>
#include "MediaRosterEx.h" #include <DataExchange.h>
#include "MediaMisc.h" #include <DormantNodeManager.h>
#include "PortPool.h" #include <MediaRosterEx.h>
#include "ServerInterface.h" #include <MediaMisc.h>
#include "DataExchange.h" #include <Notifications.h>
#include "DormantNodeManager.h" #include <PortPool.h>
#include "Notifications.h" #include <ServerInterface.h>
#include <SharedBufferList.h>
#include "TimeSourceObjectManager.h" #include "TimeSourceObjectManager.h"
namespace BPrivate { namespace media { namespace BPrivate { namespace media {
// the BMediaRoster destructor is private, // the BMediaRoster destructor is private,
@ -3206,6 +3209,8 @@ BMediaRoster::~BMediaRoster()
QueryServer(SERVER_UNREGISTER_APP, &request, sizeof(request), &reply, QueryServer(SERVER_UNREGISTER_APP, &request, sizeof(request), &reply,
sizeof(reply)); sizeof(reply));
BPrivate::SharedBufferList::Invalidate();
// Unset the global instance pointer, the destructor is also called // Unset the global instance pointer, the destructor is also called
// if a client app calls Lock(); and Quit(); directly. // if a client app calls Lock(); and Quit(); directly.
sDefaultInstance = NULL; sDefaultInstance = NULL;
@ -3238,7 +3243,8 @@ status_t BMediaRoster::_Reserved_MediaRoster_7(void *) { return B_ERROR; }
BMediaRoster::BMediaRoster() BMediaRoster::BMediaRoster()
: BLooper("_BMediaRoster_", B_URGENT_DISPLAY_PRIORITY, :
BLooper("_BMediaRoster_", B_URGENT_DISPLAY_PRIORITY,
B_LOOPER_PORT_DEFAULT_CAPACITY) B_LOOPER_PORT_DEFAULT_CAPACITY)
{ {
CALLED(); CALLED();

View File

@ -17,9 +17,18 @@
#include <string.h> #include <string.h>
#include <Autolock.h>
#include <Buffer.h> #include <Buffer.h>
#include <Locker.h>
#include "debug.h" #include <debug.h>
#include <DataExchange.h>
static BPrivate::SharedBufferList* sList;
static area_id sArea;
static int32 sRefCount;
static BLocker sLocker("shared buffer list");
namespace BPrivate { namespace BPrivate {
@ -50,21 +59,41 @@ SharedBufferList::Create(SharedBufferList** _list)
/*static*/ SharedBufferList* /*static*/ SharedBufferList*
SharedBufferList::Get(area_id id) SharedBufferList::Get()
{ {
CALLED(); CALLED();
// TODO: map this only once per team!
SharedBufferList* list; BAutolock _(sLocker);
area_id area = clone_area("shared buffer list clone", (void**)&list,
B_ANY_ADDRESS, B_READ_AREA | B_WRITE_AREA, id); if (atomic_add(&sRefCount, 1) > 0 && sList != NULL)
if (area < 0) { return sList;
ERROR("SharedBufferList::Clone() clone area: %ld err = %s\n", id,
strerror(area)); // ask media_server to get the area_id of the shared buffer list
server_get_shared_buffer_area_request areaRequest;
server_get_shared_buffer_area_reply areaReply;
if (QueryServer(SERVER_GET_SHARED_BUFFER_AREA, &areaRequest,
sizeof(areaRequest), &areaReply, sizeof(areaReply)) != B_OK) {
ERROR("SharedBufferList::Get() SERVER_GET_SHARED_BUFFER_AREA failed\n");
return NULL; return NULL;
} }
return list; sArea = clone_area("shared buffer list clone", (void**)&sList,
B_ANY_ADDRESS, B_READ_AREA | B_WRITE_AREA, areaReply.area);
if (sArea < 0) {
ERROR("SharedBufferList::Get() clone area %ld: %s\n",
areaReply.area, strerror(sArea));
return NULL;
}
return sList;
}
/*static*/ void
SharedBufferList::Invalidate()
{
delete_area(sArea);
sList = NULL;
} }
@ -72,10 +101,10 @@ void
SharedBufferList::Put() SharedBufferList::Put()
{ {
CALLED(); CALLED();
BAutolock _(sLocker);
area_id area = area_for(this); if (atomic_add(&sRefCount, -1) == 1)
if (area >= 0) Invalidate();
delete_area(area);
} }