/*
 * Copyright 2012 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "SkTLS.h"

// enable to help debug TLS storage
//#define SK_TRACE_TLS_LIFETIME


#ifdef SK_TRACE_TLS_LIFETIME
    #include "SkAtomics.h"
    static int32_t gTLSRecCount;
#endif

struct SkTLSRec {
    SkTLSRec*           fNext;
    void*               fData;
    SkTLS::CreateProc   fCreateProc;
    SkTLS::DeleteProc   fDeleteProc;

#ifdef SK_TRACE_TLS_LIFETIME
    SkTLSRec() {
        int n = sk_atomic_inc(&gTLSRecCount);
        SkDebugf(" SkTLSRec[%d]\n", n);
    }
#endif

    ~SkTLSRec() {
        if (fDeleteProc) {
            fDeleteProc(fData);
        }
        // else we leak fData, or it will be managed by the caller

#ifdef SK_TRACE_TLS_LIFETIME
        int n = sk_atomic_dec(&gTLSRecCount);
        SkDebugf("~SkTLSRec[%d]\n", n - 1);
#endif
    }
};

void SkTLS::Destructor(void* ptr) {
#ifdef SK_TRACE_TLS_LIFETIME
    SkDebugf("SkTLS::Destructor(%p)\n", ptr);
#endif

    SkTLSRec* rec = (SkTLSRec*)ptr;
    do {
        SkTLSRec* next = rec->fNext;
        delete rec;
        rec = next;
    } while (rec);
}

void* SkTLS::Get(CreateProc createProc, DeleteProc deleteProc) {
    if (nullptr == createProc) {
        return nullptr;
    }

    void* ptr = SkTLS::PlatformGetSpecific(true);

    if (ptr) {
        const SkTLSRec* rec = (const SkTLSRec*)ptr;
        do {
            if (rec->fCreateProc == createProc) {
                SkASSERT(rec->fDeleteProc == deleteProc);
                return rec->fData;
            }
        } while ((rec = rec->fNext) != nullptr);
        // not found, so create a new one
    }

    // add a new head of our change
    SkTLSRec* rec = new SkTLSRec;
    rec->fNext = (SkTLSRec*)ptr;

    SkTLS::PlatformSetSpecific(rec);

    rec->fData = createProc();
    rec->fCreateProc = createProc;
    rec->fDeleteProc = deleteProc;
    return rec->fData;
}

void* SkTLS::Find(CreateProc createProc) {
    if (nullptr == createProc) {
        return nullptr;
    }

    void* ptr = SkTLS::PlatformGetSpecific(false);

    if (ptr) {
        const SkTLSRec* rec = (const SkTLSRec*)ptr;
        do {
            if (rec->fCreateProc == createProc) {
                return rec->fData;
            }
        } while ((rec = rec->fNext) != nullptr);
    }
    return nullptr;
}

void SkTLS::Delete(CreateProc createProc) {
    if (nullptr == createProc) {
        return;
    }

    void* ptr = SkTLS::PlatformGetSpecific(false);

    SkTLSRec* curr = (SkTLSRec*)ptr;
    SkTLSRec* prev = nullptr;
    while (curr) {
        SkTLSRec* next = curr->fNext;
        if (curr->fCreateProc == createProc) {
            if (prev) {
                prev->fNext = next;
            } else {
                // we have a new head of our chain
                SkTLS::PlatformSetSpecific(next);
            }
            delete curr;
            break;
        }
        prev = curr;
        curr = next;
    }
}
