1#include "AutoDecodeCancel.h"
2
3static SkMutex  gAutoDecoderCancelMutex;
4static AutoDecoderCancel* gAutoDecoderCancel;
5#ifdef SK_DEBUG
6static int gAutoDecoderCancelCount;
7#endif
8
9AutoDecoderCancel::AutoDecoderCancel(jobject joptions,
10                                       SkImageDecoder* decoder) {
11    fJOptions = joptions;
12    fDecoder = decoder;
13
14    if (NULL != joptions) {
15        SkAutoMutexAcquire ac(gAutoDecoderCancelMutex);
16
17        // Add us as the head of the list
18        fPrev = NULL;
19        fNext = gAutoDecoderCancel;
20        if (gAutoDecoderCancel) {
21            gAutoDecoderCancel->fPrev = this;
22        }
23        gAutoDecoderCancel = this;
24
25        SkDEBUGCODE(gAutoDecoderCancelCount += 1;)
26        Validate();
27    }
28}
29
30AutoDecoderCancel::~AutoDecoderCancel() {
31    if (NULL != fJOptions) {
32        SkAutoMutexAcquire ac(gAutoDecoderCancelMutex);
33
34        // take us out of the dllist
35        AutoDecoderCancel* prev = fPrev;
36        AutoDecoderCancel* next = fNext;
37
38        if (prev) {
39            SkASSERT(prev->fNext == this);
40            prev->fNext = next;
41        } else {
42            SkASSERT(gAutoDecoderCancel == this);
43            gAutoDecoderCancel = next;
44        }
45        if (next) {
46            SkASSERT(next->fPrev == this);
47            next->fPrev = prev;
48        }
49
50        SkDEBUGCODE(gAutoDecoderCancelCount -= 1;)
51        Validate();
52    }
53}
54
55bool AutoDecoderCancel::RequestCancel(jobject joptions) {
56    SkAutoMutexAcquire ac(gAutoDecoderCancelMutex);
57
58    Validate();
59
60    AutoDecoderCancel* pair = gAutoDecoderCancel;
61    while (pair != NULL) {
62        if (pair->fJOptions == joptions) {
63            pair->fDecoder->cancelDecode();
64            return true;
65        }
66        pair = pair->fNext;
67    }
68    return false;
69}
70
71#ifdef SK_DEBUG
72// can only call this inside a lock on gAutoDecoderCancelMutex
73void AutoDecoderCancel::Validate() {
74    const int gCount = gAutoDecoderCancelCount;
75
76    if (gCount == 0) {
77        SkASSERT(gAutoDecoderCancel == NULL);
78    } else {
79        SkASSERT(gCount > 0);
80
81        AutoDecoderCancel* curr = gAutoDecoderCancel;
82        SkASSERT(curr);
83        SkASSERT(curr->fPrev == NULL);
84
85        int count = 0;
86        while (curr) {
87            count += 1;
88            SkASSERT(count <= gCount);
89            if (curr->fPrev) {
90                SkASSERT(curr->fPrev->fNext == curr);
91            }
92            if (curr->fNext) {
93                SkASSERT(curr->fNext->fPrev == curr);
94            }
95            curr = curr->fNext;
96        }
97        SkASSERT(count == gCount);
98    }
99}
100#endif
101