git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@12056 a95241bf-73f2-0310-859d-f6bbb57e9c96
113 lines
2.0 KiB
C++
113 lines
2.0 KiB
C++
// UpdateQueue.cpp
|
|
|
|
#include <new>
|
|
#include <stdio.h>
|
|
|
|
#include "HWInterface.h"
|
|
|
|
#include "UpdateQueue.h"
|
|
|
|
// constructor
|
|
UpdateQueue::UpdateQueue(HWInterface* interface)
|
|
: fInterface(interface),
|
|
fUpdateRegion(),
|
|
fUpdateExecutor(-1),
|
|
fThreadControl(-1),
|
|
fStatus(B_ERROR)
|
|
|
|
{
|
|
fThreadControl = create_sem(0, "update queue control");
|
|
if (fThreadControl >= B_OK)
|
|
fStatus = B_OK;
|
|
else
|
|
fStatus = fThreadControl;
|
|
if (fStatus == B_OK) {
|
|
fUpdateExecutor = spawn_thread(_execute_updates_, "update queue runner",
|
|
B_NORMAL_PRIORITY, this);
|
|
if (fUpdateExecutor >= B_OK) {
|
|
fStatus = B_OK;
|
|
resume_thread(fUpdateExecutor);
|
|
} else
|
|
fStatus = fUpdateExecutor;
|
|
}
|
|
}
|
|
|
|
// destructor
|
|
UpdateQueue::~UpdateQueue()
|
|
{
|
|
if (delete_sem(fThreadControl) == B_OK)
|
|
wait_for_thread(fUpdateExecutor, &fUpdateExecutor);
|
|
}
|
|
|
|
// InitCheck
|
|
status_t
|
|
UpdateQueue::InitCheck()
|
|
{
|
|
return fStatus;
|
|
}
|
|
|
|
// AddRect
|
|
void
|
|
UpdateQueue::AddRect(const BRect& rect)
|
|
{
|
|
Lock();
|
|
fUpdateRegion.Include(rect);
|
|
_Reschedule();
|
|
Unlock();
|
|
}
|
|
|
|
// _execute_updates_
|
|
int32
|
|
UpdateQueue::_execute_updates_(void* cookie)
|
|
{
|
|
UpdateQueue *gc = (UpdateQueue*)cookie;
|
|
return gc->_ExecuteUpdates();
|
|
}
|
|
|
|
// _ExecuteUpdates
|
|
int32
|
|
UpdateQueue::_ExecuteUpdates()
|
|
{
|
|
bool running = true;
|
|
while (running) {
|
|
status_t err = acquire_sem_etc(fThreadControl, 1, B_RELATIVE_TIMEOUT,
|
|
40000);
|
|
switch (err) {
|
|
case B_OK:
|
|
case B_TIMED_OUT:
|
|
// execute updates
|
|
if (Lock()) {
|
|
// if (fInterface->Lock()) {
|
|
int32 count = fUpdateRegion.CountRects();
|
|
for (int32 i = 0; i < count; i++) {
|
|
fInterface->CopyBackToFront(fUpdateRegion.RectAt(i));
|
|
}
|
|
// fInterface->Unlock();
|
|
fUpdateRegion.MakeEmpty();
|
|
// }
|
|
Unlock();
|
|
}
|
|
break;
|
|
case B_BAD_SEM_ID:
|
|
running = false;
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
// _Reschedule
|
|
//
|
|
// PRE: The object must be locked.
|
|
void
|
|
UpdateQueue::_Reschedule()
|
|
{
|
|
if (fStatus == B_OK) {
|
|
if (fUpdateRegion.Frame().IsValid())
|
|
release_sem(fThreadControl);
|
|
}
|
|
}
|
|
|