1*3294d07bSStephan Aßmus // UpdateQueue.cpp 2*3294d07bSStephan Aßmus 3*3294d07bSStephan Aßmus #include <new> 4*3294d07bSStephan Aßmus #include <stdio.h> 5*3294d07bSStephan Aßmus 6*3294d07bSStephan Aßmus #include "HWInterface.h" 7*3294d07bSStephan Aßmus 8*3294d07bSStephan Aßmus #include "UpdateQueue.h" 9*3294d07bSStephan Aßmus 10*3294d07bSStephan Aßmus // constructor 11*3294d07bSStephan Aßmus UpdateQueue::UpdateQueue(HWInterface* interface) 12*3294d07bSStephan Aßmus : fInterface(interface), 13*3294d07bSStephan Aßmus fUpdateRegion(), 14*3294d07bSStephan Aßmus fUpdateExecutor(-1), 15*3294d07bSStephan Aßmus fThreadControl(-1), 16*3294d07bSStephan Aßmus fStatus(B_ERROR) 17*3294d07bSStephan Aßmus 18*3294d07bSStephan Aßmus { 19*3294d07bSStephan Aßmus fThreadControl = create_sem(0, "update queue control"); 20*3294d07bSStephan Aßmus if (fThreadControl >= B_OK) 21*3294d07bSStephan Aßmus fStatus = B_OK; 22*3294d07bSStephan Aßmus else 23*3294d07bSStephan Aßmus fStatus = fThreadControl; 24*3294d07bSStephan Aßmus if (fStatus == B_OK) { 25*3294d07bSStephan Aßmus fUpdateExecutor = spawn_thread(_execute_updates_, "update queue runner", 26*3294d07bSStephan Aßmus B_NORMAL_PRIORITY, this); 27*3294d07bSStephan Aßmus if (fUpdateExecutor >= B_OK) { 28*3294d07bSStephan Aßmus fStatus = B_OK; 29*3294d07bSStephan Aßmus resume_thread(fUpdateExecutor); 30*3294d07bSStephan Aßmus } else 31*3294d07bSStephan Aßmus fStatus = fUpdateExecutor; 32*3294d07bSStephan Aßmus } 33*3294d07bSStephan Aßmus } 34*3294d07bSStephan Aßmus 35*3294d07bSStephan Aßmus // destructor 36*3294d07bSStephan Aßmus UpdateQueue::~UpdateQueue() 37*3294d07bSStephan Aßmus { 38*3294d07bSStephan Aßmus if (delete_sem(fThreadControl) == B_OK) 39*3294d07bSStephan Aßmus wait_for_thread(fUpdateExecutor, &fUpdateExecutor); 40*3294d07bSStephan Aßmus } 41*3294d07bSStephan Aßmus 42*3294d07bSStephan Aßmus // InitCheck 43*3294d07bSStephan Aßmus status_t 44*3294d07bSStephan Aßmus UpdateQueue::InitCheck() 45*3294d07bSStephan Aßmus { 46*3294d07bSStephan Aßmus return fStatus; 47*3294d07bSStephan Aßmus } 48*3294d07bSStephan Aßmus 49*3294d07bSStephan Aßmus // AddRect 50*3294d07bSStephan Aßmus void 51*3294d07bSStephan Aßmus UpdateQueue::AddRect(const BRect& rect) 52*3294d07bSStephan Aßmus { 53*3294d07bSStephan Aßmus Lock(); 54*3294d07bSStephan Aßmus fUpdateRegion.Include(rect); 55*3294d07bSStephan Aßmus _Reschedule(); 56*3294d07bSStephan Aßmus Unlock(); 57*3294d07bSStephan Aßmus } 58*3294d07bSStephan Aßmus 59*3294d07bSStephan Aßmus // _execute_updates_ 60*3294d07bSStephan Aßmus int32 61*3294d07bSStephan Aßmus UpdateQueue::_execute_updates_(void* cookie) 62*3294d07bSStephan Aßmus { 63*3294d07bSStephan Aßmus UpdateQueue *gc = (UpdateQueue*)cookie; 64*3294d07bSStephan Aßmus return gc->_ExecuteUpdates(); 65*3294d07bSStephan Aßmus } 66*3294d07bSStephan Aßmus 67*3294d07bSStephan Aßmus // _ExecuteUpdates 68*3294d07bSStephan Aßmus int32 69*3294d07bSStephan Aßmus UpdateQueue::_ExecuteUpdates() 70*3294d07bSStephan Aßmus { 71*3294d07bSStephan Aßmus bool running = true; 72*3294d07bSStephan Aßmus while (running) { 73*3294d07bSStephan Aßmus status_t err = acquire_sem_etc(fThreadControl, 1, B_RELATIVE_TIMEOUT, 74*3294d07bSStephan Aßmus 40000); 75*3294d07bSStephan Aßmus switch (err) { 76*3294d07bSStephan Aßmus case B_OK: 77*3294d07bSStephan Aßmus case B_TIMED_OUT: 78*3294d07bSStephan Aßmus // execute updates 79*3294d07bSStephan Aßmus if (Lock()) { 80*3294d07bSStephan Aßmus // if (fInterface->Lock()) { 81*3294d07bSStephan Aßmus int32 count = fUpdateRegion.CountRects(); 82*3294d07bSStephan Aßmus for (int32 i = 0; i < count; i++) { 83*3294d07bSStephan Aßmus fInterface->CopyBackToFront(fUpdateRegion.RectAt(i)); 84*3294d07bSStephan Aßmus } 85*3294d07bSStephan Aßmus // fInterface->Unlock(); 86*3294d07bSStephan Aßmus fUpdateRegion.MakeEmpty(); 87*3294d07bSStephan Aßmus // } 88*3294d07bSStephan Aßmus Unlock(); 89*3294d07bSStephan Aßmus } 90*3294d07bSStephan Aßmus break; 91*3294d07bSStephan Aßmus case B_BAD_SEM_ID: 92*3294d07bSStephan Aßmus running = false; 93*3294d07bSStephan Aßmus break; 94*3294d07bSStephan Aßmus default: 95*3294d07bSStephan Aßmus break; 96*3294d07bSStephan Aßmus } 97*3294d07bSStephan Aßmus } 98*3294d07bSStephan Aßmus return 0; 99*3294d07bSStephan Aßmus } 100*3294d07bSStephan Aßmus 101*3294d07bSStephan Aßmus // _Reschedule 102*3294d07bSStephan Aßmus // 103*3294d07bSStephan Aßmus // PRE: The object must be locked. 104*3294d07bSStephan Aßmus void 105*3294d07bSStephan Aßmus UpdateQueue::_Reschedule() 106*3294d07bSStephan Aßmus { 107*3294d07bSStephan Aßmus if (fStatus == B_OK) { 108*3294d07bSStephan Aßmus if (fUpdateRegion.Frame().IsValid()) 109*3294d07bSStephan Aßmus release_sem(fThreadControl); 110*3294d07bSStephan Aßmus } 111*3294d07bSStephan Aßmus } 112*3294d07bSStephan Aßmus 113