* Cleanup, BufferManager now aggregates the buffer map as well as its locker
instead of allocating them separately, no functional change. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@32153 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -2,167 +2,185 @@
|
|||||||
* Copyright 2002, Marcus Overhagen. All rights reserved.
|
* Copyright 2002, Marcus Overhagen. All rights reserved.
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
#include <MediaDefs.h>
|
|
||||||
#include <Autolock.h>
|
|
||||||
#include "BufferManager.h"
|
#include "BufferManager.h"
|
||||||
#include "SharedBufferList.h"
|
|
||||||
|
#include <Autolock.h>
|
||||||
|
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
|
#include "SharedBufferList.h"
|
||||||
|
|
||||||
|
|
||||||
BufferManager::BufferManager()
|
BufferManager::BufferManager()
|
||||||
: fSharedBufferList(_shared_buffer_list::Clone()),
|
:
|
||||||
fNextBufferId(1),
|
fSharedBufferList(_shared_buffer_list::Clone()),
|
||||||
fLocker(new BLocker("buffer manager locker")),
|
fNextBufferID(1),
|
||||||
fBufferInfoMap(new Map<media_buffer_id, buffer_info>)
|
fLocker("buffer manager locker")
|
||||||
{
|
{
|
||||||
fSharedBufferListId = area_for(fSharedBufferList);
|
fSharedBufferListID = area_for(fSharedBufferList);
|
||||||
ASSERT(fSharedBufferList!=NULL);
|
|
||||||
ASSERT(fSharedBufferListId > 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
BufferManager::~BufferManager()
|
BufferManager::~BufferManager()
|
||||||
{
|
{
|
||||||
fSharedBufferList->Unmap();
|
fSharedBufferList->Unmap();
|
||||||
delete fLocker;
|
|
||||||
delete fBufferInfoMap;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
area_id
|
area_id
|
||||||
BufferManager::SharedBufferListID()
|
BufferManager::SharedBufferListID()
|
||||||
{
|
{
|
||||||
return fSharedBufferListId;
|
return fSharedBufferListID;
|
||||||
}
|
}
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
BufferManager::RegisterBuffer(team_id teamid, media_buffer_id bufferid,
|
BufferManager::RegisterBuffer(team_id team, media_buffer_id bufferID,
|
||||||
size_t *size, int32 *flags, size_t *offset, area_id *area)
|
size_t* _size, int32* _flags, size_t* _offset, area_id* _area)
|
||||||
{
|
{
|
||||||
BAutolock lock(fLocker);
|
BAutolock lock(fLocker);
|
||||||
|
|
||||||
TRACE("RegisterBuffer team = %ld, bufferid = %ld\n", teamid, bufferid);
|
TRACE("RegisterBuffer team = %ld, bufferid = %ld\n", team, bufferID);
|
||||||
|
|
||||||
buffer_info *info;
|
buffer_info* info;
|
||||||
if (!fBufferInfoMap->Get(bufferid, &info)) {
|
if (!fBufferInfoMap.Get(bufferID, &info)) {
|
||||||
ERROR("failed to register buffer! team = %ld, bufferid = %ld\n", teamid, bufferid);
|
ERROR("failed to register buffer! team = %ld, bufferid = %ld\n", team,
|
||||||
|
bufferID);
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
info->teams.Insert(teamid);
|
info->teams.Insert(team);
|
||||||
|
|
||||||
*area = info->area;
|
*_area = info->area;
|
||||||
*offset = info->offset;
|
*_offset = info->offset;
|
||||||
*size = info->size,
|
*_size = info->size,
|
||||||
*flags = info->flags;
|
*_flags = info->flags;
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
BufferManager::RegisterBuffer(team_id teamid, size_t size, int32 flags, size_t offset, area_id area,
|
BufferManager::RegisterBuffer(team_id team, size_t size, int32 flags,
|
||||||
media_buffer_id *bufferid)
|
size_t offset, area_id area, media_buffer_id* _bufferID)
|
||||||
{
|
{
|
||||||
BAutolock lock(fLocker);
|
BAutolock lock(fLocker);
|
||||||
TRACE("RegisterBuffer team = %ld, areaid = %ld, offset = %ld, size = %ld\n", teamid, area, offset, size);
|
TRACE("RegisterBuffer team = %ld, area = %ld, offset = %ld, size = %ld\n",
|
||||||
|
team, area, offset, size);
|
||||||
|
|
||||||
void *adr;
|
void* address;
|
||||||
area_id newarea;
|
area_id clonedArea = clone_area("media_server cloned buffer", &address,
|
||||||
|
B_ANY_ADDRESS, B_READ_AREA | B_WRITE_AREA, area);
|
||||||
newarea = clone_area("media_server cloned buffer", &adr, B_ANY_ADDRESS, B_READ_AREA | B_WRITE_AREA, area);
|
if (clonedArea < 0) {
|
||||||
if (newarea <= B_OK) {
|
ERROR("RegisterBuffer: failed to clone buffer! error = %#lx, team = "
|
||||||
ERROR("RegisterBuffer: failed to clone buffer! error = %#lx, team = %ld, areaid = %ld, offset = %ld, size = %ld\n", newarea, teamid, area, offset, size);
|
"%ld, areaid = %ld, offset = %ld, size = %ld\n", clonedArea, team,
|
||||||
|
area, offset, size);
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
buffer_info info;
|
buffer_info info;
|
||||||
|
info.id = fNextBufferID++;
|
||||||
*bufferid = fNextBufferId;
|
info.area = clonedArea;
|
||||||
info.id = fNextBufferId;
|
|
||||||
info.area = newarea;
|
|
||||||
info.offset = offset;
|
info.offset = offset;
|
||||||
info.size = size;
|
info.size = size;
|
||||||
info.flags = flags;
|
info.flags = flags;
|
||||||
info.teams.Insert(teamid);
|
info.teams.Insert(team);
|
||||||
fBufferInfoMap->Insert(fNextBufferId, info);
|
|
||||||
|
|
||||||
TRACE("RegisterBuffer: done, bufferid = %ld\n", fNextBufferId);
|
*_bufferID = info.id;
|
||||||
|
|
||||||
|
fBufferInfoMap.Insert(info.id, info);
|
||||||
|
|
||||||
|
TRACE("RegisterBuffer: done, bufferID = %ld\n", info.id);
|
||||||
|
|
||||||
fNextBufferId += 1;
|
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
BufferManager::UnregisterBuffer(team_id teamid, media_buffer_id bufferid)
|
BufferManager::UnregisterBuffer(team_id team, media_buffer_id bufferID)
|
||||||
{
|
{
|
||||||
BAutolock lock(fLocker);
|
BAutolock lock(fLocker);
|
||||||
TRACE("UnregisterBuffer: team = %ld, bufferid = %ld\n", teamid, bufferid);
|
TRACE("UnregisterBuffer: team = %ld, bufferid = %ld\n", team, bufferID);
|
||||||
|
|
||||||
buffer_info *info;
|
buffer_info* info;
|
||||||
int index;
|
if (!fBufferInfoMap.Get(bufferID, &info)) {
|
||||||
|
ERROR("UnregisterBuffer: failed to unregister buffer! team = %ld, "
|
||||||
if (!fBufferInfoMap->Get(bufferid, &info)) {
|
"bufferid = %ld\n", team, bufferID);
|
||||||
ERROR("UnregisterBuffer: failed to unregister buffer! team = %ld, bufferid = %ld\n", teamid, bufferid);
|
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
index = info->teams.Find(teamid);
|
int index = info->teams.Find(team);
|
||||||
if (index < 0) {
|
if (index < 0) {
|
||||||
ERROR("UnregisterBuffer: failed to find team = %ld belonging to bufferid = %ld\n", teamid, bufferid);
|
ERROR("UnregisterBuffer: failed to find team = %ld belonging to "
|
||||||
|
"bufferID = %ld\n", team, bufferID);
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!info->teams.Remove(index)) {
|
if (!info->teams.Remove(index)) {
|
||||||
ERROR("UnregisterBuffer: failed to remove team = %ld from bufferid = %ld\n", teamid, bufferid);
|
ERROR("UnregisterBuffer: failed to remove team = %ld from bufferID "
|
||||||
|
"= %ld\n", team, bufferID);
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
TRACE("UnregisterBuffer: team = %ld removed from bufferid = %ld\n", teamid, bufferid);
|
|
||||||
|
TRACE("UnregisterBuffer: team = %ld removed from bufferID = %ld\n", team,
|
||||||
|
bufferID);
|
||||||
|
|
||||||
if (info->teams.IsEmpty()) {
|
if (info->teams.IsEmpty()) {
|
||||||
|
if (!fBufferInfoMap.Remove(bufferID)) {
|
||||||
if (!fBufferInfoMap->Remove(bufferid)) {
|
ERROR("UnregisterBuffer: failed to remove bufferID = %ld\n",
|
||||||
ERROR("UnregisterBuffer: failed to remove bufferid = %ld\n", bufferid);
|
bufferID);
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
TRACE("UnregisterBuffer: bufferid = %ld removed\n", bufferid);
|
TRACE("UnregisterBuffer: bufferID = %ld removed\n", bufferID);
|
||||||
}
|
}
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
BufferManager::CleanupTeam(team_id team)
|
BufferManager::CleanupTeam(team_id team)
|
||||||
{
|
{
|
||||||
BAutolock lock(fLocker);
|
BAutolock lock(fLocker);
|
||||||
buffer_info *info;
|
|
||||||
|
|
||||||
TRACE("BufferManager::CleanupTeam: team %ld\n", team);
|
TRACE("BufferManager::CleanupTeam: team %ld\n", team);
|
||||||
|
|
||||||
for (fBufferInfoMap->Rewind(); fBufferInfoMap->GetNext(&info); ) {
|
buffer_info* info;
|
||||||
team_id *otherteam;
|
for (fBufferInfoMap.Rewind(); fBufferInfoMap.GetNext(&info); ) {
|
||||||
for (info->teams.Rewind(); info->teams.GetNext(&otherteam); ) {
|
team_id* currentTeam;
|
||||||
if (team == *otherteam) {
|
for (info->teams.Rewind(); info->teams.GetNext(¤tTeam); ) {
|
||||||
PRINT(1, "BufferManager::CleanupTeam: removing team %ld from buffer id %ld\n", team, info->id);
|
if (team == *currentTeam) {
|
||||||
|
PRINT(1, "BufferManager::CleanupTeam: removing team %ld from "
|
||||||
|
"buffer id %ld\n", team, info->id);
|
||||||
info->teams.RemoveCurrent();
|
info->teams.RemoveCurrent();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (info->teams.IsEmpty()) {
|
if (info->teams.IsEmpty()) {
|
||||||
PRINT(1, "BufferManager::CleanupTeam: removing buffer id %ld that has no teams\n", info->id);
|
PRINT(1, "BufferManager::CleanupTeam: removing buffer id %ld that "
|
||||||
fBufferInfoMap->RemoveCurrent();
|
"has no teams\n", info->id);
|
||||||
|
fBufferInfoMap.RemoveCurrent();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
BufferManager::Dump()
|
BufferManager::Dump()
|
||||||
{
|
{
|
||||||
BAutolock lock(fLocker);
|
BAutolock lock(fLocker);
|
||||||
buffer_info *info;
|
|
||||||
printf("\n");
|
printf("\n");
|
||||||
printf("BufferManager: list of buffers follows:\n");
|
printf("BufferManager: list of buffers follows:\n");
|
||||||
for (fBufferInfoMap->Rewind(); fBufferInfoMap->GetNext(&info); ) {
|
|
||||||
printf(" buffer-id %ld, area-id %ld, offset %ld, size %ld, flags %#08lx\n",
|
buffer_info *info;
|
||||||
info->id, info->area, info->offset, info->size, info->flags);
|
for (fBufferInfoMap.Rewind(); fBufferInfoMap.GetNext(&info); ) {
|
||||||
|
printf(" buffer-id %ld, area-id %ld, offset %ld, size %ld, flags "
|
||||||
|
"%#08lx\n", info->id, info->area, info->offset, info->size,
|
||||||
|
info->flags);
|
||||||
printf(" assigned teams: ");
|
printf(" assigned teams: ");
|
||||||
team_id *team;
|
|
||||||
|
team_id* team;
|
||||||
for (info->teams.Rewind(); info->teams.GetNext(&team); ) {
|
for (info->teams.Rewind(); info->teams.GetNext(&team); ) {
|
||||||
printf("%ld, ", *team);
|
printf("%ld, ", *team);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,46 +2,54 @@
|
|||||||
* Copyright 2002, Marcus Overhagen. All rights reserved.
|
* Copyright 2002, Marcus Overhagen. All rights reserved.
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*/
|
*/
|
||||||
struct _shared_buffer_list;
|
|
||||||
|
|
||||||
|
#include <Locker.h>
|
||||||
|
#include <MediaDefs.h>
|
||||||
|
|
||||||
#include <TMap.h>
|
#include <TMap.h>
|
||||||
#include <TList.h>
|
#include <TList.h>
|
||||||
|
|
||||||
class BufferManager
|
|
||||||
{
|
struct _shared_buffer_list;
|
||||||
|
|
||||||
|
|
||||||
|
class BufferManager {
|
||||||
public:
|
public:
|
||||||
BufferManager();
|
BufferManager();
|
||||||
~BufferManager();
|
~BufferManager();
|
||||||
|
|
||||||
area_id SharedBufferListID();
|
area_id SharedBufferListID();
|
||||||
|
|
||||||
status_t RegisterBuffer(team_id teamid, media_buffer_id bufferid,
|
status_t RegisterBuffer(team_id team,
|
||||||
size_t *size, int32 *flags, size_t *offset, area_id *area);
|
media_buffer_id bufferID, size_t* _size,
|
||||||
|
int32* _flags, size_t* _offset, area_id* _area);
|
||||||
|
|
||||||
status_t RegisterBuffer(team_id teamid, size_t size, int32 flags, size_t offset, area_id area,
|
status_t RegisterBuffer(team_id team, size_t size,
|
||||||
media_buffer_id *bufferid);
|
int32 flags, size_t offset, area_id area,
|
||||||
|
media_buffer_id* _bufferID);
|
||||||
|
|
||||||
status_t UnregisterBuffer(team_id teamid, media_buffer_id bufferid);
|
status_t UnregisterBuffer(team_id team,
|
||||||
|
media_buffer_id bufferID);
|
||||||
void CleanupTeam(team_id teamid);
|
|
||||||
|
|
||||||
void Dump();
|
void CleanupTeam(team_id team);
|
||||||
|
|
||||||
|
void Dump();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct buffer_info
|
struct buffer_info {
|
||||||
{
|
media_buffer_id id;
|
||||||
media_buffer_id id;
|
area_id area;
|
||||||
area_id area;
|
size_t offset;
|
||||||
size_t offset;
|
size_t size;
|
||||||
size_t size;
|
int32 flags;
|
||||||
int32 flags;
|
List<team_id> teams;
|
||||||
List<team_id> teams;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
_shared_buffer_list * fSharedBufferList;
|
_shared_buffer_list* fSharedBufferList;
|
||||||
area_id fSharedBufferListId;
|
area_id fSharedBufferListID;
|
||||||
media_buffer_id fNextBufferId;
|
media_buffer_id fNextBufferID;
|
||||||
BLocker * fLocker;
|
BLocker fLocker;
|
||||||
Map<media_buffer_id, buffer_info> *fBufferInfoMap;
|
Map<media_buffer_id, buffer_info> fBufferInfoMap;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -708,7 +708,7 @@ ServerApp::HandleMessage(int32 code, void *data, size_t size)
|
|||||||
request->info.offset, request->info.area,
|
request->info.offset, request->info.area,
|
||||||
&reply.info.buffer);
|
&reply.info.buffer);
|
||||||
} else {
|
} else {
|
||||||
reply.info = request->info; //buffer id is kept
|
reply.info = request->info; // buffer id is kept
|
||||||
status = gBufferManager->RegisterBuffer(request->team,
|
status = gBufferManager->RegisterBuffer(request->team,
|
||||||
request->info.buffer, &reply.info.size, &reply.info.flags,
|
request->info.buffer, &reply.info.size, &reply.info.flags,
|
||||||
&reply.info.offset, &reply.info.area);
|
&reply.info.offset, &reply.info.area);
|
||||||
@@ -720,7 +720,7 @@ ServerApp::HandleMessage(int32 code, void *data, size_t size)
|
|||||||
case SERVER_UNREGISTER_BUFFER:
|
case SERVER_UNREGISTER_BUFFER:
|
||||||
{
|
{
|
||||||
const server_unregister_buffer_command *cmd = reinterpret_cast<
|
const server_unregister_buffer_command *cmd = reinterpret_cast<
|
||||||
const server_unregister_buffer_command *>(data);
|
const server_unregister_buffer_command *>(data);
|
||||||
|
|
||||||
gBufferManager->UnregisterBuffer(cmd->team, cmd->bufferid);
|
gBufferManager->UnregisterBuffer(cmd->team, cmd->bufferid);
|
||||||
break;
|
break;
|
||||||
@@ -736,7 +736,7 @@ ServerApp::HandleMessage(int32 code, void *data, size_t size)
|
|||||||
|
|
||||||
rv = gMMediaFilesManager->RewindTypes(
|
rv = gMMediaFilesManager->RewindTypes(
|
||||||
&types, &reply.count);
|
&types, &reply.count);
|
||||||
if(reply.count>0) {
|
if (reply.count > 0) {
|
||||||
// we create an area here, and pass it to the library,
|
// we create an area here, and pass it to the library,
|
||||||
// where it will be deleted.
|
// where it will be deleted.
|
||||||
char *start_addr;
|
char *start_addr;
|
||||||
@@ -780,7 +780,7 @@ ServerApp::HandleMessage(int32 code, void *data, size_t size)
|
|||||||
&items, &reply.count);
|
&items, &reply.count);
|
||||||
// we create an area here, and pass it to the library,
|
// we create an area here, and pass it to the library,
|
||||||
// where it will be deleted.
|
// where it will be deleted.
|
||||||
if(reply.count>0) {
|
if (reply.count > 0) {
|
||||||
char *start_addr;
|
char *start_addr;
|
||||||
size_t size = ((reply.count * B_MEDIA_NAME_LENGTH)
|
size_t size = ((reply.count * B_MEDIA_NAME_LENGTH)
|
||||||
+ B_PAGE_SIZE - 1) & ~(B_PAGE_SIZE - 1);
|
+ B_PAGE_SIZE - 1) & ~(B_PAGE_SIZE - 1);
|
||||||
|
|||||||
Reference in New Issue
Block a user