Your node needs to delete the buffer group corresponding to any connection that is disconnected or whenever the node is deleted. Until your node does so, the other end of the connection will be blocked waiting for the buffer group to be deleted.
| Class Overview |
BBufferGroup(size_t size,
int32 numBuffers = 3,
uint32 placement = B_ANY_ADDRESS,
uint32 lock = B_FULL_LOCK);
BBufferGroup();
BBufferGroup(int32 numBuffers,
const buffer_id * bufferList);
The first form of the constructor creates a
BBufferGroup
with some number
of BBuffer
s
already allocated by the group. These buffers will all live
within a single Kernel Kit area, allocated by the group. The group tries
to allocate an area with properties specified by the placement
and lock
arguments, large enough to hold numBuffers
buffers of the specified size
(there may be some padding added).
The second form of the constructor creates a BBufferGroup
but doesn't
create any buffers for it. You should add
BBuffer
s
to the group before trying to use it.
The third form of the constructor creates a BBufferGroup
that contains
the specified list of buffers. bufferList
points to an array of buffer
IDs for the buffers to be controlled by the group, and numBuffers
is the
number of buffers in the list. This version of the constructor isn't one
you'll use very often.
Before using any buffers from a new BBufferGroup
,
call InitCheck()
to
determine if any errors occurred while creating the group.
~BBufferGroup();
Releases all memory used by the BBufferGroup
,
including the
BBuffer
s it
controls.
Keep in mind that
AddBuffer()
clones the buffer area. This destructor
releases the clones, but it's your application's job to release the
original area you added.
Your node needs to delete the buffer group corresponding to any connection that is disconnected or whenever the node is deleted. Until your node does so, the other end of the connection will be blocked waiting for the buffer group to be deleted.
status_t AddBuffer(const buffer_clone_info& info);
Given the buffer_clone_info, this function clones the buffer and adds the
clone to the BBufferGroup
. Normally you'll
fill out the buffer_clone_info
structure yourself.
Since the buffer is cloned, you'll need to delete the original memory
area specified by the buffer_clone_info structure yourself when you're no
longer using it; the BBufferGroup
won't do it for you.
You shouldn't pass the result of a
BBuffer::CloneInfo()
call to this
function, as doing so would create an "alias" buffer for the same memory
area. This is probably not the effect you want.
Return Code | Description |
---|---|
| No error adding the buffer to the group. |
| Couldn't clone the buffer into the |
status_t AddBuffersTo(BMessage* message,
const char* name,
bool needLock = true);
Adds the group's buffers to the specified
message
, storing them in an array with the
specified name
. If
needLock
is true
, the
BBufferGroup
is locked before performing the
operation, then unlocked when finished; otherwise, you guarantee that the
buffers won't go anywhere during the
AddBuffersTo()
call.
The buffers are added by ID number, and are therefore in int32 format.
Return Code | Description |
---|---|
| No error adding the buffers to the message. |
Errors from
AddInt32()
.
status_t CountBuffers(int32* outBufferCount);
Returns, in outBufferCount
, the
number of buffers in the group.
Return Code | Description |
---|---|
| The number of buffers was returned successfully. |
| Invalid |
status_t GetBufferList(int32 listCount,
BBuffer** outBuffers);
Returns a list of all the buffers in the group. When calling
GetBufferList()
, pass in
outBuffers
a pointer to an array of
BBuffer
pointers that you want to be filled with pointers to the group's buffers,
and specify the number of elements in the array in listCount
.
Return Code | Description |
---|---|
| No errors. |
|
|
status_t InitCheck();
Returns the error code resulting from the construction of the
BBufferGroup
.
Return Code | Description |
---|---|
| The new group was created successfully. |
| Couldn't allocate the buffers for the group. |
Area errors. | See Areas in The Kernel Kit. |
status_t ReclaimAllBuffers();
If you pass a buffer group to some other
BBufferProducer
but pass true
for willReclaim
in the
BBufferConsumer::SetOutputBuffersFor()
call, you can later reclaim the buffers into the
BBufferGroup
by calling
ReclaimAllBuffers()
.
ReclaimAllBuffers()
will return
B_OK
when all buffers are accounted for,
or return an error if buffers can't be reclaimed.
If you have buffers that reference some object that might go away (such
as a BBitmap
),
you should call ReclaimAllBuffers()
on the group and
delete the BBufferGroup
before that object goes away.
Before reclaiming your buffers, be sure to call
BBufferConsumer
::SetOutputBuffersFor
(output
, NULL
)
to let the Media Kit know
your producer no longer has permission to use them. If you forget this
step, the producer will hang onto the buffers until it's deleted, and
your ReclaimAllBuffers()
call will hang, possibly forever.
Return Code | Description |
---|---|
| All buffers reclaimed successfully. |
| Some buffers couldn't be reclaimed. |
BBuffer* RequestBuffer(size_t size,
bigtime_t timeout = B_INFINITE_TIMEOUT);
status_t RequestBuffer(BBuffer* outBuffer,
bigtime_t timeout = B_INFINITE_TIMEOUT);
Returns a pointer to a
BBuffer
of at least the specified size that your
BBufferProducer
subclass can put data into, then pass on to a
media_destination.
If there isn't a suitable buffer available, the call
will block until either a buffer becomes available (in which case the
buffer is returned) or the specified timeout
is reached.
If you pass a timeout
value that's less
than zero, RequestBuffer()
will
return NULL
immediately if there's no buffer available, otherwise it will
return a pointer to a buffer you can use.
In BeOS Release 4.5, the timeout is ignored (unless you specify a
negative value); B_INFINITE_TIMEOUT
is always used, regardless of the
value you specify.
RequestBuffer()
doesn't use the buffer flags; instead, you can look at
the buffers within a BBufferGroup
to find a specific buffer to request
yourself, based on the value returned by
BBuffer::Flags()
or
BBuffer::SizeUsed()
,
for example. Use the second form of RequestBuffer()
to
obtain a specific buffer.
The first version of RequestBuffer()
returns NULL
if no buffer can be
obtained, and sets errno
to the appropriate error code. The second
version returns an appropriate error code.
Don't call RequestBuffer()
while an outstanding
ReclaimAllBuffers()
request is pending. To make sure that doesn't happen, a buffer producer
should be designed to not know about the old group anymore once
SetBufferGroup()
is called to change its buffer group.
Return Code | Description |
---|---|
| No errors. |
| Buffers are in the process of being reclaimed. |
| A miscellaneous error occurred. |
status_t RequestError();
Returns the last
RequestBuffer()
error. This is useful if
RequestBuffer()
returns NULL
.
status_t WaitForBuffers();
Waits until the currently pending buffer reclamation is finished, then returns. If there isn't a buffer reclamation in progress, returns immediately.
Return Code | Description |
---|---|
| No errors. |
Semaphore errors. | Unable to acquire the semaphore used to detect that buffer reclamation is done. |