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