101 lines
2.5 KiB
C++
101 lines
2.5 KiB
C++
|
#include "AutoDecodeCancel.h"
|
||
|
|
||
|
static SkMutex gAutoDecoderCancelMutex;
|
||
|
static AutoDecoderCancel* gAutoDecoderCancel;
|
||
|
#ifdef SK_DEBUG
|
||
|
static int gAutoDecoderCancelCount;
|
||
|
#endif
|
||
|
|
||
|
AutoDecoderCancel::AutoDecoderCancel(jobject joptions,
|
||
|
SkImageDecoder* decoder) {
|
||
|
fJOptions = joptions;
|
||
|
fDecoder = decoder;
|
||
|
|
||
|
if (NULL != joptions) {
|
||
|
SkAutoMutexAcquire ac(gAutoDecoderCancelMutex);
|
||
|
|
||
|
// Add us as the head of the list
|
||
|
fPrev = NULL;
|
||
|
fNext = gAutoDecoderCancel;
|
||
|
if (gAutoDecoderCancel) {
|
||
|
gAutoDecoderCancel->fPrev = this;
|
||
|
}
|
||
|
gAutoDecoderCancel = this;
|
||
|
|
||
|
SkDEBUGCODE(gAutoDecoderCancelCount += 1;)
|
||
|
Validate();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
AutoDecoderCancel::~AutoDecoderCancel() {
|
||
|
if (NULL != fJOptions) {
|
||
|
SkAutoMutexAcquire ac(gAutoDecoderCancelMutex);
|
||
|
|
||
|
// take us out of the dllist
|
||
|
AutoDecoderCancel* prev = fPrev;
|
||
|
AutoDecoderCancel* next = fNext;
|
||
|
|
||
|
if (prev) {
|
||
|
SkASSERT(prev->fNext == this);
|
||
|
prev->fNext = next;
|
||
|
} else {
|
||
|
SkASSERT(gAutoDecoderCancel == this);
|
||
|
gAutoDecoderCancel = next;
|
||
|
}
|
||
|
if (next) {
|
||
|
SkASSERT(next->fPrev == this);
|
||
|
next->fPrev = prev;
|
||
|
}
|
||
|
|
||
|
SkDEBUGCODE(gAutoDecoderCancelCount -= 1;)
|
||
|
Validate();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
bool AutoDecoderCancel::RequestCancel(jobject joptions) {
|
||
|
SkAutoMutexAcquire ac(gAutoDecoderCancelMutex);
|
||
|
|
||
|
Validate();
|
||
|
|
||
|
AutoDecoderCancel* pair = gAutoDecoderCancel;
|
||
|
while (pair != NULL) {
|
||
|
if (pair->fJOptions == joptions) {
|
||
|
pair->fDecoder->cancelDecode();
|
||
|
return true;
|
||
|
}
|
||
|
pair = pair->fNext;
|
||
|
}
|
||
|
return false;
|
||
|
}
|
||
|
|
||
|
#ifdef SK_DEBUG
|
||
|
// can only call this inside a lock on gAutoDecoderCancelMutex
|
||
|
void AutoDecoderCancel::Validate() {
|
||
|
const int gCount = gAutoDecoderCancelCount;
|
||
|
|
||
|
if (gCount == 0) {
|
||
|
SkASSERT(gAutoDecoderCancel == NULL);
|
||
|
} else {
|
||
|
SkASSERT(gCount > 0);
|
||
|
|
||
|
AutoDecoderCancel* curr = gAutoDecoderCancel;
|
||
|
SkASSERT(curr);
|
||
|
SkASSERT(curr->fPrev == NULL);
|
||
|
|
||
|
int count = 0;
|
||
|
while (curr) {
|
||
|
count += 1;
|
||
|
SkASSERT(count <= gCount);
|
||
|
if (curr->fPrev) {
|
||
|
SkASSERT(curr->fPrev->fNext == curr);
|
||
|
}
|
||
|
if (curr->fNext) {
|
||
|
SkASSERT(curr->fNext->fPrev == curr);
|
||
|
}
|
||
|
curr = curr->fNext;
|
||
|
}
|
||
|
SkASSERT(count == gCount);
|
||
|
}
|
||
|
}
|
||
|
#endif
|