* Rewrote BBufferGroup header.
* Cleaned up the source file, no functional change (intended). git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@32139 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -1,82 +1,68 @@
|
|||||||
/*******************************************************************************
|
/*
|
||||||
/
|
* Copyright 2009, Haiku Inc. All Rights Reserved.
|
||||||
/ File: BufferGroup.h
|
* Distributed under the terms of the MIT License.
|
||||||
/
|
*/
|
||||||
/ Description: A BBufferGroup organizes sets of BBuffers so that you can request
|
#ifndef _BUFFER_GROUP_H
|
||||||
/ and reclaim them.
|
|
||||||
/
|
|
||||||
/ Copyright 1997-98, Be Incorporated, All Rights Reserved
|
|
||||||
/
|
|
||||||
*******************************************************************************/
|
|
||||||
|
|
||||||
#if !defined(_BUFFER_GROUP_H)
|
|
||||||
#define _BUFFER_GROUP_H
|
#define _BUFFER_GROUP_H
|
||||||
|
|
||||||
|
|
||||||
#include <MediaDefs.h>
|
#include <MediaDefs.h>
|
||||||
|
|
||||||
|
|
||||||
class BBuffer;
|
class BBuffer;
|
||||||
struct _shared_buffer_list;
|
struct _shared_buffer_list;
|
||||||
|
|
||||||
class BBufferGroup
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
|
|
||||||
BBufferGroup(
|
class BBufferGroup {
|
||||||
size_t size,
|
public:
|
||||||
int32 count = 3,
|
BBufferGroup(size_t size, int32 count = 3,
|
||||||
uint32 placement = B_ANY_ADDRESS,
|
uint32 placement = B_ANY_ADDRESS,
|
||||||
uint32 lock = B_FULL_LOCK);
|
uint32 lock = B_FULL_LOCK);
|
||||||
explicit BBufferGroup();
|
explicit BBufferGroup();
|
||||||
BBufferGroup(
|
BBufferGroup(int32 count,
|
||||||
int32 count,
|
|
||||||
const media_buffer_id* buffers);
|
const media_buffer_id* buffers);
|
||||||
~BBufferGroup(); /* BBufferGroup is NOT a virtual class!!! */
|
~BBufferGroup();
|
||||||
|
|
||||||
status_t InitCheck();
|
status_t InitCheck();
|
||||||
|
|
||||||
/* use this function to add buffers you created on your own */
|
status_t AddBuffer(const buffer_clone_info& info,
|
||||||
status_t AddBuffer(
|
BBuffer** _buffer = NULL);
|
||||||
const buffer_clone_info & info,
|
|
||||||
BBuffer ** out_buffer = NULL);
|
|
||||||
|
|
||||||
BBuffer * RequestBuffer(
|
BBuffer* RequestBuffer(size_t size,
|
||||||
size_t size,
|
|
||||||
bigtime_t timeout = B_INFINITE_TIMEOUT);
|
bigtime_t timeout = B_INFINITE_TIMEOUT);
|
||||||
status_t RequestBuffer(
|
status_t RequestBuffer(BBuffer* buffer,
|
||||||
BBuffer * buffer,
|
|
||||||
bigtime_t timeout = B_INFINITE_TIMEOUT);
|
bigtime_t timeout = B_INFINITE_TIMEOUT);
|
||||||
status_t RequestError(); /* return last RequestBuffer error, useful if NULL is returned */
|
|
||||||
|
|
||||||
status_t CountBuffers(
|
status_t RequestError();
|
||||||
int32 * out_count);
|
|
||||||
status_t GetBufferList(
|
status_t CountBuffers(int32* _count);
|
||||||
int32 buf_count,
|
status_t GetBufferList(int32 bufferCount,
|
||||||
BBuffer ** out_buffers);
|
BBuffer** _buffers);
|
||||||
|
|
||||||
status_t WaitForBuffers();
|
status_t WaitForBuffers();
|
||||||
status_t ReclaimAllBuffers();
|
status_t ReclaimAllBuffers();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/* in BeOS R5 this is a deprecated api, from BeOS R4 times */
|
// deprecated BeOS R4 API
|
||||||
status_t AddBuffersTo(BMessage * message, const char * name, bool needLock=true);
|
status_t AddBuffersTo(BMessage* message, const char* name,
|
||||||
|
bool needLock);
|
||||||
|
|
||||||
status_t InitBufferGroup(); /* used internally */
|
BBufferGroup(const BBufferGroup& other);
|
||||||
BBufferGroup(const BBufferGroup &); /* not implemented */
|
BBufferGroup& operator=(const BBufferGroup& other);
|
||||||
BBufferGroup& operator=(const BBufferGroup&); /* not implemented */
|
|
||||||
|
|
||||||
|
status_t _Init();
|
||||||
|
|
||||||
|
private:
|
||||||
friend struct _shared_buffer_list;
|
friend struct _shared_buffer_list;
|
||||||
|
|
||||||
status_t fInitError;
|
status_t fInitError;
|
||||||
status_t fRequestError;
|
status_t fRequestError;
|
||||||
int32 fBufferCount;
|
int32 fBufferCount;
|
||||||
_shared_buffer_list* fBufferList;
|
_shared_buffer_list* fBufferList;
|
||||||
|
|
||||||
// this is a BBufferGroup specific semaphore used for reclaiming BBuffers of this group
|
|
||||||
// is also is a system wide unique identifier of this group
|
|
||||||
sem_id fReclaimSem;
|
sem_id fReclaimSem;
|
||||||
|
|
||||||
uint32 _reserved_buffer_group_[9];
|
uint32 _reserved[9];
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* _BUFFER_GROUP_H */
|
|
||||||
|
|
||||||
|
#endif // _BUFFER_GROUP_H
|
||||||
|
|||||||
+146
-162
@@ -27,69 +27,21 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
#include <BufferGroup.h>
|
#include <BufferGroup.h>
|
||||||
|
|
||||||
#include <Buffer.h>
|
#include <Buffer.h>
|
||||||
|
|
||||||
#include "debug.h"
|
#include "debug.h"
|
||||||
#include "SharedBufferList.h"
|
|
||||||
#include "DataExchange.h"
|
#include "DataExchange.h"
|
||||||
|
#include "SharedBufferList.h"
|
||||||
/*************************************************************
|
|
||||||
* private BBufferGroup
|
|
||||||
*************************************************************/
|
|
||||||
|
|
||||||
status_t
|
|
||||||
BBufferGroup::InitBufferGroup()
|
|
||||||
{
|
|
||||||
CALLED();
|
|
||||||
|
|
||||||
// some defaults
|
|
||||||
fBufferList = 0;
|
|
||||||
fReclaimSem = B_ERROR;
|
|
||||||
fInitError = B_ERROR;
|
|
||||||
fRequestError = B_ERROR;
|
|
||||||
fBufferCount = 0;
|
|
||||||
|
|
||||||
// create the reclaim semaphore
|
|
||||||
fReclaimSem = create_sem(0,"buffer reclaim sem");
|
|
||||||
if (fReclaimSem < B_OK) {
|
|
||||||
ERROR("BBufferGroup::InitBufferGroup: couldn't create fReclaimSem\n");
|
|
||||||
fInitError = (status_t)fReclaimSem;
|
|
||||||
return fInitError;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ask media_server to get the area_id of the shared buffer list
|
|
||||||
server_get_shared_buffer_area_request area_request;
|
|
||||||
server_get_shared_buffer_area_reply area_reply;
|
|
||||||
if (QueryServer(SERVER_GET_SHARED_BUFFER_AREA, &area_request, sizeof(area_request), &area_reply, sizeof(area_reply)) != B_OK) {
|
|
||||||
ERROR("BBufferGroup::InitBufferGroup: SERVER_GET_SHARED_BUFFER_AREA failed\n");
|
|
||||||
fInitError = B_ERROR;
|
|
||||||
return fInitError;
|
|
||||||
}
|
|
||||||
ASSERT(area_reply.area > 0);
|
|
||||||
|
|
||||||
fBufferList = _shared_buffer_list::Clone(area_reply.area);
|
|
||||||
if (fBufferList == NULL) {
|
|
||||||
ERROR("BBufferGroup::InitBufferGroup: _shared_buffer_list::Clone failed\n");
|
|
||||||
fInitError = B_ERROR;
|
|
||||||
return fInitError;
|
|
||||||
}
|
|
||||||
|
|
||||||
fInitError = B_OK;
|
|
||||||
return fInitError;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************
|
BBufferGroup::BBufferGroup(size_t size, int32 count, uint32 placement,
|
||||||
* public BBufferGroup
|
|
||||||
*************************************************************/
|
|
||||||
|
|
||||||
BBufferGroup::BBufferGroup(size_t size,
|
|
||||||
int32 count,
|
|
||||||
uint32 placement,
|
|
||||||
uint32 lock)
|
uint32 lock)
|
||||||
{
|
{
|
||||||
CALLED();
|
CALLED();
|
||||||
if (InitBufferGroup() != B_OK)
|
if (_Init() != B_OK)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// This one is easy. We need to create "count" BBuffers,
|
// This one is easy. We need to create "count" BBuffers,
|
||||||
@@ -99,100 +51,76 @@ BBufferGroup::BBufferGroup(size_t size,
|
|||||||
// then we delete our area. This way BBuffers are
|
// then we delete our area. This way BBuffers are
|
||||||
// independent from the BBufferGroup
|
// independent from the BBufferGroup
|
||||||
|
|
||||||
void *start_addr;
|
|
||||||
area_id buffer_area;
|
|
||||||
size_t area_size;
|
|
||||||
buffer_clone_info bci;
|
|
||||||
BBuffer *buffer;
|
|
||||||
|
|
||||||
// don't allow all placement parameter values
|
// don't allow all placement parameter values
|
||||||
if (placement != B_ANY_ADDRESS && placement != B_ANY_KERNEL_ADDRESS) {
|
if (placement != B_ANY_ADDRESS && placement != B_ANY_KERNEL_ADDRESS) {
|
||||||
ERROR("BBufferGroup: placement != B_ANY_ADDRESS && placement != B_ANY_KERNEL_ADDRESS (0x%08lx)\n",placement);
|
ERROR("BBufferGroup: placement != B_ANY_ADDRESS "
|
||||||
|
"&& placement != B_ANY_KERNEL_ADDRESS (0x%08lx)\n", placement);
|
||||||
placement = B_ANY_ADDRESS;
|
placement = B_ANY_ADDRESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
// first we roundup for a better placement in memory
|
// first we roundup for a better placement in memory
|
||||||
int allocsize = (size + 63) & ~63;
|
size_t allocSize = (size + 63) & ~63;
|
||||||
|
|
||||||
// now we create the area
|
// now we create the area
|
||||||
area_size = ((allocsize * count) + (B_PAGE_SIZE - 1)) & ~(B_PAGE_SIZE - 1);
|
size_t areaSize
|
||||||
|
= ((allocSize * count) + B_PAGE_SIZE - 1) & ~(B_PAGE_SIZE - 1);
|
||||||
|
|
||||||
buffer_area = create_area("some buffers area", &start_addr,placement,area_size,lock,B_READ_AREA | B_WRITE_AREA);
|
void* startAddress;
|
||||||
if (buffer_area < B_OK) {
|
area_id bufferArea = create_area("some buffers area", &startAddress,
|
||||||
ERROR("BBufferGroup: failed to allocate %ld bytes area\n",area_size);
|
placement, areaSize, lock, B_READ_AREA | B_WRITE_AREA);
|
||||||
fInitError = (status_t)buffer_area;
|
if (bufferArea < 0) {
|
||||||
|
ERROR("BBufferGroup: failed to allocate %ld bytes area\n", areaSize);
|
||||||
|
fInitError = (status_t)bufferArea;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
fBufferCount = count;
|
buffer_clone_info info;
|
||||||
|
|
||||||
for (int32 i = 0; i < count; i++) {
|
for (int32 i = 0; i < count; i++) {
|
||||||
bci.area = buffer_area;
|
info.area = bufferArea;
|
||||||
bci.offset = i * allocsize;
|
info.offset = i * allocSize;
|
||||||
bci.size = size;
|
info.size = size;
|
||||||
buffer = new BBuffer(bci);
|
|
||||||
if (0 == buffer->Data()) {
|
fInitError = AddBuffer(info);
|
||||||
// BBuffer::Data() will return 0 if an error occured
|
if (fInitError != B_OK)
|
||||||
ERROR("BBufferGroup: error while creating buffer\n");
|
|
||||||
delete buffer;
|
|
||||||
fInitError = B_ERROR;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (B_OK != fBufferList->AddBuffer(fReclaimSem,buffer)) {
|
|
||||||
ERROR("BBufferGroup: error when adding buffer\n");
|
|
||||||
delete buffer;
|
|
||||||
fInitError = B_ERROR;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
delete_area(bufferArea);
|
||||||
}
|
}
|
||||||
|
|
||||||
delete_area(buffer_area);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* explicit */
|
|
||||||
BBufferGroup::BBufferGroup()
|
BBufferGroup::BBufferGroup()
|
||||||
{
|
{
|
||||||
CALLED();
|
CALLED();
|
||||||
if (InitBufferGroup() != B_OK)
|
if (_Init() != B_OK)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// this one simply creates an empty BBufferGroup
|
// this one simply creates an empty BBufferGroup
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
BBufferGroup::BBufferGroup(int32 count,
|
BBufferGroup::BBufferGroup(int32 count, const media_buffer_id* buffers)
|
||||||
const media_buffer_id *buffers)
|
|
||||||
{
|
{
|
||||||
CALLED();
|
CALLED();
|
||||||
if (InitBufferGroup() != B_OK)
|
if (_Init() != B_OK)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// XXX we need to make sure that a media_buffer_id is only added once to each group
|
// TODO: we need to make sure that a media_buffer_id is only added
|
||||||
|
// once to each group
|
||||||
|
|
||||||
// this one creates "BBuffer"s from "media_buffer_id"s passed
|
// this one creates "BBuffer"s from "media_buffer_id"s passed
|
||||||
// by the application.
|
// by the application.
|
||||||
|
|
||||||
fBufferCount = count;
|
buffer_clone_info info;
|
||||||
|
|
||||||
buffer_clone_info bci;
|
|
||||||
BBuffer *buffer;
|
|
||||||
for (int32 i = 0; i < count; i++) {
|
for (int32 i = 0; i < count; i++) {
|
||||||
bci.buffer = buffers[i];
|
info.buffer = buffers[i];
|
||||||
buffer = new BBuffer(bci);
|
|
||||||
if (0 == buffer->Data()) {
|
fInitError = AddBuffer(info);
|
||||||
// BBuffer::Data() will return 0 if an error occured
|
if (fInitError != B_OK)
|
||||||
ERROR("BBufferGroup(2): error while creating buffer\n");
|
|
||||||
delete buffer;
|
|
||||||
fInitError = B_ERROR;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (B_OK != fBufferList->AddBuffer(fReclaimSem,buffer)) {
|
|
||||||
ERROR("BBufferGroup(2): error when adding buffer\n");
|
|
||||||
delete buffer;
|
|
||||||
fInitError = B_ERROR;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -201,7 +129,7 @@ BBufferGroup::~BBufferGroup()
|
|||||||
CALLED();
|
CALLED();
|
||||||
if (fBufferList)
|
if (fBufferList)
|
||||||
fBufferList->Terminate(fReclaimSem);
|
fBufferList->Terminate(fReclaimSem);
|
||||||
if (fReclaimSem >= B_OK)
|
|
||||||
delete_sem(fReclaimSem);
|
delete_sem(fReclaimSem);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -215,41 +143,44 @@ BBufferGroup::InitCheck()
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
BBufferGroup::AddBuffer(const buffer_clone_info &info,
|
BBufferGroup::AddBuffer(const buffer_clone_info& info, BBuffer** _buffer)
|
||||||
BBuffer **out_buffer)
|
|
||||||
{
|
{
|
||||||
CALLED();
|
CALLED();
|
||||||
if (fInitError != B_OK)
|
if (fInitError != B_OK)
|
||||||
return B_NO_INIT;
|
return B_NO_INIT;
|
||||||
|
|
||||||
// XXX we need to make sure that a media_buffer_id is only added once to each group
|
// TODO: we need to make sure that a media_buffer_id is only added
|
||||||
|
// once to each group
|
||||||
|
|
||||||
BBuffer *buffer;
|
BBuffer* buffer = new(std::nothrow) BBuffer(info);
|
||||||
buffer = new BBuffer(info);
|
if (buffer == NULL)
|
||||||
if (0 == buffer->Data()) {
|
return B_NO_MEMORY;
|
||||||
// BBuffer::Data() will return 0 if an error occured
|
|
||||||
ERROR("BBufferGroup::AddBuffer: error while creating buffer\n");
|
if (buffer->Data() == NULL) {
|
||||||
|
// BBuffer::Data() will return NULL if an error occured
|
||||||
|
ERROR("BBufferGroup: error while creating buffer\n");
|
||||||
delete buffer;
|
delete buffer;
|
||||||
return B_ERROR;
|
return B_ERROR;
|
||||||
}
|
}
|
||||||
if (B_OK != fBufferList->AddBuffer(fReclaimSem,buffer)) {
|
|
||||||
ERROR("BBufferGroup::AddBuffer: error when adding buffer\n");
|
status_t status = fBufferList->AddBuffer(fReclaimSem, buffer);
|
||||||
|
if (status != B_OK) {
|
||||||
|
ERROR("BBufferGroup: error when adding buffer\n");
|
||||||
delete buffer;
|
delete buffer;
|
||||||
fInitError = B_ERROR;
|
return status;
|
||||||
return B_ERROR;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
atomic_add(&fBufferCount, 1);
|
atomic_add(&fBufferCount, 1);
|
||||||
|
|
||||||
if (out_buffer != 0)
|
if (_buffer != NULL)
|
||||||
*out_buffer = buffer;
|
*_buffer = buffer;
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
BBuffer*
|
BBuffer*
|
||||||
BBufferGroup::RequestBuffer(size_t size,
|
BBufferGroup::RequestBuffer(size_t size, bigtime_t timeout)
|
||||||
bigtime_t timeout)
|
|
||||||
{
|
{
|
||||||
CALLED();
|
CALLED();
|
||||||
if (fInitError != B_OK)
|
if (fInitError != B_OK)
|
||||||
@@ -262,16 +193,16 @@ BBufferGroup::RequestBuffer(size_t size,
|
|||||||
status_t status;
|
status_t status;
|
||||||
|
|
||||||
buffer = NULL;
|
buffer = NULL;
|
||||||
status = fBufferList->RequestBuffer(fReclaimSem, fBufferCount, size, 0, &buffer, timeout);
|
status = fBufferList->RequestBuffer(fReclaimSem, fBufferCount, size, 0,
|
||||||
|
&buffer, timeout);
|
||||||
fRequestError = status;
|
fRequestError = status;
|
||||||
|
|
||||||
return (status == B_OK) ? buffer : NULL;
|
return status == B_OK ? buffer : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
BBufferGroup::RequestBuffer(BBuffer *buffer,
|
BBufferGroup::RequestBuffer(BBuffer* buffer, bigtime_t timeout)
|
||||||
bigtime_t timeout)
|
|
||||||
{
|
{
|
||||||
CALLED();
|
CALLED();
|
||||||
if (fInitError != B_OK)
|
if (fInitError != B_OK)
|
||||||
@@ -281,7 +212,8 @@ BBufferGroup::RequestBuffer(BBuffer *buffer,
|
|||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
status_t status;
|
status_t status;
|
||||||
status = fBufferList->RequestBuffer(fReclaimSem, fBufferCount, 0, 0, &buffer, timeout);
|
status = fBufferList->RequestBuffer(fReclaimSem, fBufferCount, 0, 0,
|
||||||
|
&buffer, timeout);
|
||||||
fRequestError = status;
|
fRequestError = status;
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
@@ -300,29 +232,28 @@ BBufferGroup::RequestError()
|
|||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
BBufferGroup::CountBuffers(int32 *out_count)
|
BBufferGroup::CountBuffers(int32* _count)
|
||||||
{
|
{
|
||||||
CALLED();
|
CALLED();
|
||||||
if (fInitError != B_OK)
|
if (fInitError != B_OK)
|
||||||
return B_NO_INIT;
|
return B_NO_INIT;
|
||||||
|
|
||||||
*out_count = fBufferCount;
|
*_count = fBufferCount;
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
BBufferGroup::GetBufferList(int32 buf_count,
|
BBufferGroup::GetBufferList(int32 bufferCount, BBuffer** _buffers)
|
||||||
BBuffer **out_buffers)
|
|
||||||
{
|
{
|
||||||
CALLED();
|
CALLED();
|
||||||
if (fInitError != B_OK)
|
if (fInitError != B_OK)
|
||||||
return B_NO_INIT;
|
return B_NO_INIT;
|
||||||
|
|
||||||
if (buf_count <= 0 || buf_count > fBufferCount)
|
if (bufferCount <= 0 || bufferCount > fBufferCount)
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
return fBufferList->GetBufferList(fReclaimSem,buf_count,out_buffers);
|
return fBufferList->GetBufferList(fReclaimSem, bufferCount, _buffers);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -333,25 +264,26 @@ BBufferGroup::WaitForBuffers()
|
|||||||
if (fInitError != B_OK)
|
if (fInitError != B_OK)
|
||||||
return B_NO_INIT;
|
return B_NO_INIT;
|
||||||
|
|
||||||
// XXX this function is not really useful anyway, and will
|
// TODO: this function is not really useful anyway, and will
|
||||||
// XXX not work exactly as documented, but it is close enough
|
// not work exactly as documented, but it is close enough
|
||||||
|
|
||||||
if (fBufferCount < 0)
|
if (fBufferCount < 0)
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
if (fBufferCount == 0)
|
if (fBufferCount == 0)
|
||||||
return B_OK;
|
return B_OK;
|
||||||
|
|
||||||
// we need to wait until at least one buffer belonging to this group is reclaimed.
|
// We need to wait until at least one buffer belonging to this group is
|
||||||
// this has happened when can aquire "fReclaimSem"
|
// reclaimed.
|
||||||
|
// This has happened when can aquire "fReclaimSem"
|
||||||
|
|
||||||
status_t status;
|
status_t status;
|
||||||
while (B_INTERRUPTED == (status = acquire_sem(fReclaimSem)))
|
while ((status = acquire_sem(fReclaimSem)) == B_INTERRUPTED)
|
||||||
;
|
;
|
||||||
|
if (status != B_OK)
|
||||||
if (status != B_OK) // some error happened
|
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
// we need to release the "fReclaimSem" now, else we would block requesting of new buffers
|
// we need to release the "fReclaimSem" now, else we would block
|
||||||
|
// requesting of new buffers
|
||||||
|
|
||||||
return release_sem(fReclaimSem);
|
return release_sem(fReclaimSem);
|
||||||
}
|
}
|
||||||
@@ -364,7 +296,8 @@ BBufferGroup::ReclaimAllBuffers()
|
|||||||
if (fInitError != B_OK)
|
if (fInitError != B_OK)
|
||||||
return B_NO_INIT;
|
return B_NO_INIT;
|
||||||
|
|
||||||
// because additional BBuffers might get added to this group betweeen acquire and release
|
// because additional BBuffers might get added to this group betweeen
|
||||||
|
// acquire and release
|
||||||
int32 count = fBufferCount;
|
int32 count = fBufferCount;
|
||||||
|
|
||||||
if (count < 0)
|
if (count < 0)
|
||||||
@@ -373,29 +306,26 @@ BBufferGroup::ReclaimAllBuffers()
|
|||||||
return B_OK;
|
return B_OK;
|
||||||
|
|
||||||
// we need to wait until all BBuffers belonging to this group are reclaimed.
|
// we need to wait until all BBuffers belonging to this group are reclaimed.
|
||||||
// this has happened when the "fReclaimSem" can be aquired "fBufferCount" times
|
// this has happened when the "fReclaimSem" can be aquired "fBufferCount"
|
||||||
|
// times
|
||||||
|
|
||||||
status_t status;
|
status_t status;
|
||||||
while (B_INTERRUPTED == (status = acquire_sem_etc(fReclaimSem, count, 0, 0)))
|
do {
|
||||||
;
|
status = acquire_sem_etc(fReclaimSem, count, 0, 0);
|
||||||
|
} while (status == B_INTERRUPTED);
|
||||||
|
|
||||||
if (status != B_OK) // some error happened
|
if (status != B_OK)
|
||||||
return status;
|
return status;
|
||||||
|
|
||||||
// we need to release the "fReclaimSem" now, else we would block requesting of new buffers
|
// we need to release the "fReclaimSem" now, else we would block
|
||||||
|
// requesting of new buffers
|
||||||
|
|
||||||
return release_sem_etc(fReclaimSem, count, 0);
|
return release_sem_etc(fReclaimSem, count, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*************************************************************
|
|
||||||
* private BBufferGroup
|
|
||||||
*************************************************************/
|
|
||||||
|
|
||||||
/* not implemented */
|
// #pragma mark - deprecated BeOS R4 API
|
||||||
/*
|
|
||||||
BBufferGroup::BBufferGroup(const BBufferGroup &)
|
|
||||||
BBufferGroup & BBufferGroup::operator=(const BBufferGroup &)
|
|
||||||
*/
|
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
BBufferGroup::AddBuffersTo(BMessage* message, const char* name, bool needLock)
|
BBufferGroup::AddBuffersTo(BMessage* message, const char* name, bool needLock)
|
||||||
@@ -414,21 +344,75 @@ BBufferGroup::AddBuffersTo(BMessage * message, const char * name, bool needLock)
|
|||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
BBuffer** buffers;
|
BBuffer** buffers;
|
||||||
status_t status;
|
|
||||||
int32 count;
|
int32 count;
|
||||||
|
|
||||||
count = fBufferCount;
|
count = fBufferCount;
|
||||||
buffers = new BBuffer * [count];
|
buffers = new BBuffer * [count];
|
||||||
|
|
||||||
if (B_OK != (status = GetBufferList(count,buffers)))
|
status_t status = GetBufferList(count, buffers);
|
||||||
|
if (status != B_OK)
|
||||||
goto end;
|
goto end;
|
||||||
|
|
||||||
for (int32 i = 0; i < count; i++)
|
for (int32 i = 0; i < count; i++) {
|
||||||
if (B_OK != (status = message->AddInt32(name,int32(buffers[i]->ID()))))
|
status = message->AddInt32(name, int32(buffers[i]->ID()));
|
||||||
|
if (status != B_OK)
|
||||||
goto end;
|
goto end;
|
||||||
|
}
|
||||||
|
|
||||||
end:
|
end:
|
||||||
delete [] buffers;
|
delete [] buffers;
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark - private methods
|
||||||
|
|
||||||
|
|
||||||
|
/* not implemented */
|
||||||
|
//BBufferGroup::BBufferGroup(const BBufferGroup &)
|
||||||
|
//BBufferGroup & BBufferGroup::operator=(const BBufferGroup &)
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
BBufferGroup::_Init()
|
||||||
|
{
|
||||||
|
CALLED();
|
||||||
|
|
||||||
|
// some defaults in case we drop out early
|
||||||
|
fBufferList = 0;
|
||||||
|
fInitError = B_ERROR;
|
||||||
|
fRequestError = B_ERROR;
|
||||||
|
fBufferCount = 0;
|
||||||
|
|
||||||
|
// Create the reclaim semaphore
|
||||||
|
// This is also used as a system wide unique identifier for this group
|
||||||
|
fReclaimSem = create_sem(0, "buffer reclaim sem");
|
||||||
|
if (fReclaimSem < B_OK) {
|
||||||
|
ERROR("BBufferGroup::InitBufferGroup: couldn't create fReclaimSem\n");
|
||||||
|
fInitError = (status_t)fReclaimSem;
|
||||||
|
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 = _shared_buffer_list::Clone(areaReply.area);
|
||||||
|
if (fBufferList == NULL) {
|
||||||
|
ERROR("BBufferGroup::InitBufferGroup: _shared_buffer_list::Clone "
|
||||||
|
"failed\n");
|
||||||
|
fInitError = B_ERROR;
|
||||||
|
return fInitError;
|
||||||
|
}
|
||||||
|
|
||||||
|
fInitError = B_OK;
|
||||||
|
return fInitError;
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user