// same as base-class DeQueue method, except no RunIfNotReady/PendForExec is called (since all events are processed in a loop)
// (i.e. PendForExec control is done in the loop in Run)
OsclAny* OmxEventHandlerThreadSafeCallbackAO::DeQueue(OsclReturnCode &stat)
{
    OsclAny *pData;
    OsclProcStatus::eOsclProcError sema_status;

    stat = OsclSuccess;

    // Protect the queue while accessing it:
    Mutex.Lock();

    if (Q->NumElem == 0)
    {
        // nothing to de-queue
        stat = OsclFailure;
        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "OmxEventHandlerThreadSafeCallbackAO::DeQueue() - No events in the queue - return ()"));
        Mutex.Unlock();

        return NULL;
    }

    pData = (Q->pFirst[Q->index_out]).pData;

    Q->index_out++;
    // roll-over the index
    if (Q->index_out == Q->MaxNumElements)
        Q->index_out = 0;

    Q->NumElem--;

    // check if there is need to call waitforevent
    if ((Q->NumElem) == 0)
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "OmxEventHandlerThreadSafeCallbackAO::Run() - No more events, call PendForExec()"));
        PendForExec();
        stat = OsclPending; // let the Run know that the last event was pulled out of the queue
        // so that it can get out of the loop
    }


    //release queue access
    Mutex.Unlock();

    // Signal the semaphore that controls the remote thread.
    // The remote thread might be blocked and waiting for an event to be processed in case the event queue is full
    sema_status = RemoteThreadCtrlSema.Signal();
    if (sema_status != OsclProcStatus::SUCCESS_ERROR)
    {
        stat = OsclFailure;
        return NULL;
    }

    return pData;
}
void LipSyncDummyOutputMIO::QueueCommandResponse(CommandResponse& aResp)
{
    PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE,
                    (0, "LipSyncDummyOutputMIO::QueueCommandResponse(), aResp.CmdId is %d ", aResp.iCmdId));
    //queue a command response and schedule processing.
    iCommandResponseQueue.push_back(aResp);

    //schedule the AO.
    if (!IsBusy())
        PendForExec();
    if (IsAdded() && iStatus == OSCL_REQUEST_PENDING)
        PendComplete(OSCL_REQUEST_ERR_NONE);
}
OSCL_EXPORT_REF ThreadSafeQueue::ThreadSafeQueue()
        : OsclActiveObject(OsclActiveObject::EPriorityNominal, "ThreadSafeQueue")
{
    iObserver = NULL;
    iCounter = 1;
    if (OsclThread::GetId(iThreadId) != OsclProcStatus::SUCCESS_ERROR)
        OsclError::Leave(OsclErrSystemCallFailed);
#if USE_SEM_WAIT
    iQueueReadySem.Create();
#endif
    iQueueMut.Create();
    AddToScheduler();
    PendForExec();
    iQueueReadySem.Signal();
}
void ThreadSafeQueue::Run()
{
    iQueueMut.Lock();
    PendForExec();
#if USE_SEM_WAIT
    iQueueReadySem.Signal();
#endif
    uint32 count = iQueue.size();
    ThreadSafeQueueObserver* obs = iObserver;
    iQueueMut.Unlock();

    //note: don't do the callback under the lock, in order to allow
    //de-queueing the data in the callback.  this creates the possibility
    //that queue size may not equal "count" in the callback.
    if (count && obs)
        obs->ThreadSafeQueueDataAvailable(this);
}
// same as base-class DeQueue method, except no RunIfNotReady/PendForExec is called (since all events are processed in a loop)
// (i.e. PendForExec control is done in the loop in Run)
OsclAny* EventHandlerThreadSafeCallbackAOEnc::DeQueue(OsclReturnCode &stat)
{
    // Note: this method executes in the context of threadsafe AO (in the node thread)

    OsclAny *pData;

    stat = OsclSuccess;

    // Protect the queue while accessing it:
    Mutex.Lock();

    if (Q->NumElem == 0)
    {
        // nothing to de-queue
        stat = OsclFailure;
        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "EventHandlerThreadSafeCallbackAOEnc::DeQueue() - No events in the queue - return ()"));
        Mutex.Unlock();

        return NULL;
    }

    pData = (Q->pFirst[Q->index_out]).pData;

    Q->index_out++;
    // roll-over the index
    if (Q->index_out == Q->MaxNumElements)
        Q->index_out = 0;

    Q->NumElem--;

    // check if there is need to call waitforevent
    if ((Q->NumElem) == 0)
    {
        PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger, PVLOGMSG_STACK_TRACE, (0, "EventHandlerThreadSafeCallbackAOEnc::Run() - No more events, call PendForExec()"));
        PendForExec();
        stat = OsclPending; // let the Run know that the last event was pulled out of the queue
        // so that it can get out of the loop
    }


    //release queue access
    Mutex.Unlock();

    return pData;
}
OsclAny* OsclSocketRequestAO::NewRequest(const uint32 size)
{
    //Activate the AO.  The socket server will complete the request.
    PendForExec();

    bool reallocate = (!iParam || size != iParamSize);

    //Cleanup any previous parameters.
    CleanupParam(reallocate);

    LOGINFOMED((0, "OsclSocket(0x%x): New Request %s", SocketI(), TPVSocketFxnStr[iContainer.iSocketFxn]));

    //Allocate space for new parameters, or recycle current space.
    if (reallocate)
    {
        iParamSize = size;
        return Alloc().ALLOCATE(size);
    }
    else
        return iParam;
}
OsclAny* AndroidAudioInputThreadSafeCallbackAO::Dequeue(OsclReturnCode &status)
{
    OsclAny *param;
    OsclProcStatus::eOsclProcError sema_status;

    status = OsclSuccess;

    Mutex.Lock();
    if(Q->NumElem == 0)
    {
        status = OsclFailure;
        Mutex.Unlock();
        return NULL;
    }
    
    param = (Q->pFirst[Q->index_out]).pData;
    Q->index_out++;
    if(Q->index_out == Q->MaxNumElements)
        Q->index_out = 0;
    Q->NumElem--;
    if(Q->NumElem == 0)
    {
        // Call PendForExec() only when there are no more elements in the queue
        // Else, continue in the do-while loop
        PendForExec();
        status = OsclPending;
    }
    Mutex.Unlock();

    sema_status = RemoteThreadCtrlSema.Signal();
    if(sema_status != OsclProcStatus::SUCCESS_ERROR)
    {
        status = OsclFailure;
        return NULL;
    }
    return param;
}
//////////// Request AO //////////////////////
void OsclDNSRequestAO::NewRequest()
{
    PendForExec();
    LOGINFOMED((0, "OsclSocket: New Request %s", TPVDNSFxnStr[iDNSMethod->iDNSFxn]));
}