Author: axeld Date: 2009-12-05 12:52:01 +0100 (Sat, 05 Dec 2009) New Revision: 34502 Changeset: http://dev.haiku-os.org/changeset/34502/haiku Modified: haiku/trunk/headers/private/media/SharedBufferList.h haiku/trunk/src/kits/media/Buffer.cpp haiku/trunk/src/kits/media/BufferGroup.cpp haiku/trunk/src/kits/media/MediaRoster.cpp haiku/trunk/src/kits/media/SharedBufferList.cpp Log: * 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. Modified: haiku/trunk/headers/private/media/SharedBufferList.h =================================================================== --- haiku/trunk/headers/private/media/SharedBufferList.h 2009-12-05 11:16:02 UTC (rev 34501) +++ haiku/trunk/headers/private/media/SharedBufferList.h 2009-12-05 11:52:01 UTC (rev 34502) @@ -16,7 +16,8 @@ class SharedBufferList { public: static area_id Create(SharedBufferList** _list); - static SharedBufferList* Get(area_id area); + static SharedBufferList* Get(); + static void Invalidate(); void Put(); void DeleteGroupAndPut(sem_id groupReclaimSem); Modified: haiku/trunk/src/kits/media/Buffer.cpp =================================================================== --- haiku/trunk/src/kits/media/Buffer.cpp 2009-12-05 11:16:02 UTC (rev 34501) +++ haiku/trunk/src/kits/media/Buffer.cpp 2009-12-05 11:52:01 UTC (rev 34502) @@ -201,16 +201,7 @@ if (info.area == 0 && info.buffer == 0) return; - // 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("BBuffer::BBuffer: SERVER_GET_SHARED_BUFFER_AREA failed\n"); - return; - } - - fBufferList = BPrivate::SharedBufferList::Get(areaReply.area); + fBufferList = BPrivate::SharedBufferList::Get(); if (fBufferList == NULL) { ERROR("BBuffer::BBuffer: _shared_buffer_list::Clone() failed\n"); return; Modified: haiku/trunk/src/kits/media/BufferGroup.cpp =================================================================== --- haiku/trunk/src/kits/media/BufferGroup.cpp 2009-12-05 11:16:02 UTC (rev 34501) +++ haiku/trunk/src/kits/media/BufferGroup.cpp 2009-12-05 11:52:01 UTC (rev 34502) @@ -393,18 +393,7 @@ return fInitError; } - // 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("BBufferGroup::InitBufferGroup: SERVER_GET_SHARED_BUFFER_AREA " - "failed\n"); - fInitError = B_ERROR; - return fInitError; - } - - fBufferList = BPrivate::SharedBufferList::Get(areaReply.area); + fBufferList = BPrivate::SharedBufferList::Get(); if (fBufferList == NULL) { ERROR("BBufferGroup::InitBufferGroup: SharedBufferList::Get() " "failed\n"); Modified: haiku/trunk/src/kits/media/MediaRoster.cpp =================================================================== --- haiku/trunk/src/kits/media/MediaRoster.cpp 2009-12-05 11:16:02 UTC (rev 34501) +++ haiku/trunk/src/kits/media/MediaRoster.cpp 2009-12-05 11:52:01 UTC (rev 34502) @@ -57,16 +57,19 @@ #include <AppMisc.h> -#include "debug.h" -#include "MediaRosterEx.h" -#include "MediaMisc.h" -#include "PortPool.h" -#include "ServerInterface.h" -#include "DataExchange.h" -#include "DormantNodeManager.h" -#include "Notifications.h" +#include <debug.h> +#include <DataExchange.h> +#include <DormantNodeManager.h> +#include <MediaRosterEx.h> +#include <MediaMisc.h> +#include <Notifications.h> +#include <PortPool.h> +#include <ServerInterface.h> +#include <SharedBufferList.h> + #include "TimeSourceObjectManager.h" + namespace BPrivate { namespace media { // the BMediaRoster destructor is private, @@ -3206,6 +3209,8 @@ QueryServer(SERVER_UNREGISTER_APP, &request, sizeof(request), &reply, sizeof(reply)); + BPrivate::SharedBufferList::Invalidate(); + // Unset the global instance pointer, the destructor is also called // if a client app calls Lock(); and Quit(); directly. sDefaultInstance = NULL; @@ -3238,7 +3243,8 @@ BMediaRoster::BMediaRoster() - : BLooper("_BMediaRoster_", B_URGENT_DISPLAY_PRIORITY, + : + BLooper("_BMediaRoster_", B_URGENT_DISPLAY_PRIORITY, B_LOOPER_PORT_DEFAULT_CAPACITY) { CALLED(); Modified: haiku/trunk/src/kits/media/SharedBufferList.cpp =================================================================== --- haiku/trunk/src/kits/media/SharedBufferList.cpp 2009-12-05 11:16:02 UTC (rev 34501) +++ haiku/trunk/src/kits/media/SharedBufferList.cpp 2009-12-05 11:52:01 UTC (rev 34502) @@ -17,11 +17,20 @@ #include <string.h> +#include <Autolock.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 { @@ -50,32 +59,52 @@ /*static*/ SharedBufferList* -SharedBufferList::Get(area_id id) +SharedBufferList::Get() { CALLED(); - // TODO: map this only once per team! - SharedBufferList* list; - area_id area = clone_area("shared buffer list clone", (void**)&list, - B_ANY_ADDRESS, B_READ_AREA | B_WRITE_AREA, id); - if (area < 0) { - ERROR("SharedBufferList::Clone() clone area: %ld err = %s\n", id, - strerror(area)); + BAutolock _(sLocker); + + if (atomic_add(&sRefCount, 1) > 0 && sList != NULL) + return sList; + + // 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 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; +} + + void SharedBufferList::Put() { CALLED(); + BAutolock _(sLocker); - area_id area = area_for(this); - if (area >= 0) - delete_area(area); + if (atomic_add(&sRefCount, -1) == 1) + Invalidate(); }