/*
 * Copyright (C) 2011 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "CallbackProtector.h"
#include "sllog.h"

#include <media/stagefright/foundation/ADebug.h>

//--------------------------------------------------------------------------------------------------
namespace android {


CallbackProtector::CallbackProtector() : RefBase(),
        mSafeToEnterCb(true),
        mCbCount(0)
#ifdef USE_DEBUG
        , mCallbackThread(NULL),
        mCallbackTid(0),
        mRequesterThread(NULL),
        mRequesterTid(0)
#endif
{
}


CallbackProtector::~CallbackProtector() {
    Mutex::Autolock _l(mLock);
    if (mCbCount) {
        SL_LOGE("Callback protector detected an active callback after destroy");
    }

}


// static
bool CallbackProtector::enterCbIfOk(const sp<CallbackProtector> &protector) {
    if (protector != 0) {
        return protector->enterCb();
    } else {
        SL_LOGE("Callback protector is missing");
        return false;
    }
}


bool CallbackProtector::enterCb() {
    Mutex::Autolock _l(mLock);
    if (mSafeToEnterCb) {
        mCbCount++;
#ifdef USE_DEBUG
        if (mCbCount > 1) {
            SL_LOGV("Callback protector allowed multiple or nested callback entry: %u", mCbCount);
        } else {
            mCallbackThread = pthread_self();
            mCallbackTid = gettid();
        }
#endif
    } else {
#ifdef USE_DEBUG
        SL_LOGV("Callback protector denied callback entry by thread %p tid %d during destroy"
                " requested by thread %p tid %d",
                (void *) pthread_self(), gettid(),
                (void *) mRequesterThread, mRequesterTid);
#else
        SL_LOGV("Callback protector denied callback entry during destroy");
#endif
    }
    return mSafeToEnterCb;
}


void CallbackProtector::exitCb() {
    Mutex::Autolock _l(mLock);

    CHECK(mCbCount > 0);
    mCbCount--;

    if (mCbCount == 0) {
        if (!mSafeToEnterCb) {
#ifdef USE_DEBUG
            SL_LOGV("Callback protector detected return from callback by thread %p tid %d during"
                    " destroy requested by thread %p tid %d",
                    (void *) mCallbackThread, mCallbackTid,
                    (void *) mRequesterThread, mRequesterTid);
#else
            SL_LOGV("Callback protector detected return from callback during destroy");
#endif
            mCbExitedCondition.broadcast();
        }
#ifdef USE_DEBUG
        mCallbackThread = NULL;
        mCallbackTid = 0;
#endif
    }
}


void CallbackProtector::requestCbExitAndWait() {
    Mutex::Autolock _l(mLock);
    mSafeToEnterCb = false;
#ifdef USE_DEBUG
    mRequesterThread = pthread_self();
    mRequesterTid = gettid();
#endif
    while (mCbCount) {
#ifdef USE_DEBUG
        SL_LOGV("Callback protector detected in-progress callback by thread %p tid %d during"
                " blocking destroy requested by thread %p tid %d",
                (void *) mCallbackThread, mCallbackTid,
                (void *) pthread_self(), gettid());
#else
        SL_LOGV("Callback protector detected in-progress callback during blocking destroy");
#endif
        mCbExitedCondition.wait(mLock);
    }
}


void CallbackProtector::requestCbExit() {
    Mutex::Autolock _l(mLock);
    mSafeToEnterCb = false;
#ifdef USE_DEBUG
    mRequesterThread = pthread_self();
    mRequesterTid = gettid();
#endif
    if (mCbCount) {
#ifdef USE_DEBUG
        SL_LOGV("Callback protector detected in-progress callback by thread %p tid %d during"
                " non-blocking destroy requested by thread %p tid %d",
                (void *) mCallbackThread, mCallbackTid,
                (void *) pthread_self(), gettid());
#else
        SL_LOGV("Callback protector detected in-progress callback during non-blocking destroy");
#endif
    }
}

} // namespace android
