Files
haiku-beta6/src/servers/media/BufferManager.cpp
T

172 lines
4.4 KiB
C++
Raw Normal View History

/*
* Copyright 2002, Marcus Overhagen. All rights reserved.
* Distributed under the terms of the MIT License.
*/
2002-07-09 12:24:59 +00:00
#include <MediaDefs.h>
#include <Autolock.h>
#include "BufferManager.h"
2002-07-10 19:59:20 +00:00
#include "SharedBufferList.h"
2002-07-09 12:24:59 +00:00
#include "debug.h"
BufferManager::BufferManager()
: fSharedBufferList(_shared_buffer_list::Clone()),
fSharedBufferListId(-1),
fNextBufferId(1),
fLocker(new BLocker("buffer manager locker")),
fBufferInfoMap(new Map<media_buffer_id, buffer_info>)
2002-07-09 12:24:59 +00:00
{
fSharedBufferListId = area_for(fSharedBufferList);
2002-07-09 12:24:59 +00:00
}
BufferManager::~BufferManager()
{
fSharedBufferList->Unmap();
delete fLocker;
delete fBufferInfoMap;
2002-07-09 12:24:59 +00:00
}
area_id
BufferManager::SharedBufferListID()
{
return fSharedBufferListId;
2002-07-09 12:24:59 +00:00
}
status_t
BufferManager::RegisterBuffer(team_id teamid, media_buffer_id bufferid,
size_t *size, int32 *flags, size_t *offset, area_id *area)
{
BAutolock lock(fLocker);
TRACE("RegisterBuffer team = %ld, bufferid = %ld\n", teamid, bufferid);
2002-07-09 12:24:59 +00:00
buffer_info *info;
if (!fBufferInfoMap->Get(bufferid, &info)) {
2003-06-19 14:53:41 +00:00
ERROR("failed to register buffer! team = %ld, bufferid = %ld\n", teamid, bufferid);
return B_ERROR;
}
2002-07-09 12:24:59 +00:00
info->teams.Insert(teamid);
*area = info->area;
*offset = info->offset;
*size = info->size,
*flags = info->flags;
return B_OK;
2002-07-09 12:24:59 +00:00
}
status_t
BufferManager::RegisterBuffer(team_id teamid, size_t size, int32 flags, size_t offset, area_id area,
media_buffer_id *bufferid)
{
BAutolock lock(fLocker);
TRACE("RegisterBuffer team = %ld, areaid = %ld, offset = %ld, size = %ld\n", teamid, area, offset, size);
2002-07-09 12:24:59 +00:00
void *adr;
area_id newarea;
newarea = clone_area("media_server cloned buffer", &adr, B_ANY_ADDRESS, B_READ_AREA | B_WRITE_AREA, area);
2002-07-09 12:24:59 +00:00
if (newarea <= B_OK) {
2003-06-19 14:53:41 +00:00
ERROR("RegisterBuffer: failed to clone buffer! error = %#lx, team = %ld, areaid = %ld, offset = %ld, size = %ld\n", newarea, teamid, area, offset, size);
2002-07-09 12:24:59 +00:00
return B_ERROR;
}
buffer_info info;
2002-07-09 12:24:59 +00:00
*bufferid = fNextBufferId;
info.id = fNextBufferId;
info.area = newarea;
info.offset = offset;
info.size = size;
info.flags = flags;
info.teams.Insert(teamid);
fBufferInfoMap->Insert(fNextBufferId, info);
TRACE("RegisterBuffer: done, bufferid = %ld\n", fNextBufferId);
fNextBufferId += 1;
2002-07-09 12:24:59 +00:00
return B_OK;
}
status_t
BufferManager::UnregisterBuffer(team_id teamid, media_buffer_id bufferid)
{
BAutolock lock(fLocker);
TRACE("UnregisterBuffer: team = %ld, bufferid = %ld\n", teamid, bufferid);
2002-07-09 12:24:59 +00:00
buffer_info *info;
int index;
2002-07-09 12:24:59 +00:00
if (!fBufferInfoMap->Get(bufferid, &info)) {
2003-06-19 14:53:41 +00:00
ERROR("UnregisterBuffer: failed to unregister buffer! team = %ld, bufferid = %ld\n", teamid, bufferid);
return B_ERROR;
}
index = info->teams.Find(teamid);
if (index < 0) {
2003-06-19 14:53:41 +00:00
ERROR("UnregisterBuffer: failed to find team = %ld belonging to bufferid = %ld\n", teamid, bufferid);
return B_ERROR;
}
if (!info->teams.Remove(index)) {
2003-06-19 14:53:41 +00:00
ERROR("UnregisterBuffer: failed to remove team = %ld from bufferid = %ld\n", teamid, bufferid);
return B_ERROR;
}
TRACE("UnregisterBuffer: team = %ld removed from bufferid = %ld\n", teamid, bufferid);
if (info->teams.IsEmpty()) {
if (!fBufferInfoMap->Remove(bufferid)) {
2003-06-19 14:53:41 +00:00
ERROR("UnregisterBuffer: failed to remove bufferid = %ld\n", bufferid);
return B_ERROR;
2002-07-09 12:24:59 +00:00
}
TRACE("UnregisterBuffer: bufferid = %ld removed\n", bufferid);
2002-07-09 12:24:59 +00:00
}
return B_OK;
2002-07-09 12:24:59 +00:00
}
2002-11-24 00:27:09 +00:00
void
BufferManager::CleanupTeam(team_id team)
2002-11-24 00:27:09 +00:00
{
BAutolock lock(fLocker);
buffer_info *info;
TRACE("BufferManager::CleanupTeam: team %ld\n", team);
for (fBufferInfoMap->Rewind(); fBufferInfoMap->GetNext(&info); ) {
team_id *otherteam;
for (info->teams.Rewind(); info->teams.GetNext(&otherteam); ) {
if (team == *otherteam) {
2003-06-19 14:53:41 +00:00
PRINT(1, "BufferManager::CleanupTeam: removing team %ld from buffer id %ld\n", team, info->id);
info->teams.RemoveCurrent();
}
}
if (info->teams.IsEmpty()) {
2003-06-19 14:53:41 +00:00
PRINT(1, "BufferManager::CleanupTeam: removing buffer id %ld that has no teams\n", info->id);
fBufferInfoMap->RemoveCurrent();
}
}
2002-11-24 00:27:09 +00:00
}
2002-07-09 12:24:59 +00:00
void
2002-12-10 18:18:50 +00:00
BufferManager::Dump()
2002-07-09 12:24:59 +00:00
{
BAutolock lock(fLocker);
buffer_info *info;
2002-12-10 18:18:50 +00:00
printf("\n");
printf("BufferManager: list of buffers follows:\n");
for (fBufferInfoMap->Rewind(); fBufferInfoMap->GetNext(&info); ) {
2002-12-10 18:18:50 +00:00
printf(" buffer-id %ld, area-id %ld, offset %ld, size %ld, flags %#08lx\n",
info->id, info->area, info->offset, info->size, info->flags);
2002-12-10 18:18:50 +00:00
printf(" assigned teams: ");
team_id *team;
for (info->teams.Rewind(); info->teams.GetNext(&team); ) {
2002-12-10 18:18:50 +00:00
printf("%ld, ", *team);
}
2002-12-10 18:18:50 +00:00
printf("\n");
2002-07-09 12:24:59 +00:00
}
2002-12-10 18:18:50 +00:00
printf("BufferManager: list end\n");
2002-07-09 12:24:59 +00:00
}