blob: 18adc930f692966c8d6dfd906ca0bb974518cbec [file] [log] [blame]
/* ------------------------------------------------------------------
* Copyright (C) 1998-2009 PacketVideo
*
* 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 "osclconfig_proc.h"
#include "oscl_scheduler_threadcontext.h"
#include "oscl_scheduler.h"
#include "oscl_error.h"
#include "oscl_error_imp.h"
#include "oscl_thread.h"
OSCL_EXPORT_REF PVThreadContext::PVThreadContext()
{
iOpen = false;
iScheduler = NULL;
}
OSCL_EXPORT_REF PVThreadContext::~PVThreadContext()
{
}
void PVThreadContext::LeaveIfWrongThread(PVThreadContext &a)
//static routine to verify thread context.
{
if (!a.IsSameThreadContext())
OsclError::Leave(OsclErrThreadContextIncorrect);
}
OSCL_EXPORT_REF bool PVThreadContext::IsSameThreadContext()
{
if (!iOpen)
return false;//unknown
//check calling thread context against
//this one.
TOsclThreadId id;
int32 result = OsclThread::GetId(id);
if (result != OsclProcStatus::SUCCESS_ERROR)
OsclError::Leave(OsclErrSystemCallFailed);
return OsclThread::CompareId(id, iThreadId);
}
OSCL_EXPORT_REF void PVThreadContext::EnterThreadContext()
{
//Save thread ID.
int32 result = OsclThread::GetId(iThreadId);
if (result != OsclProcStatus::SUCCESS_ERROR)
OsclError::Leave(OsclErrSystemCallFailed);
//Set current thread scheduler.
iScheduler = OsclExecScheduler::GetScheduler();
if (!iScheduler)
{
//There must be a pv scheduler.
OsclError::Leave(OsclErrNotInstalled);
}
iOpen = true;
}
OSCL_EXPORT_REF void PVThreadContext::ExitThreadContext()
{
iScheduler = NULL;
iOpen = false;
}
void PVThreadContext::PendComplete(PVActiveBase *pvbase, int32 aReason, TPVThreadContext aCallingContext)
{
//request can be completed from any thread.
if (!iOpen)
OsclError::Leave(OsclErrInvalidState);//thread context unknown
//status can be anything but 'pending'
if (aReason == OSCL_REQUEST_PENDING)
OsclError::Leave(OsclErrInvalidState);//bad request status
//use PV scheduler mechanism to complete requests.
//first determine the calling context if possible.
if (aCallingContext == EPVThreadContext_Undetermined && IsSameThreadContext())
iScheduler->PendComplete(pvbase, aReason, EPVThreadContext_InThread);
else
iScheduler->PendComplete(pvbase, aReason, aCallingContext);
}
OSCL_EXPORT_REF uint32 PVThreadContext::Id()
//static routine to get current context.
{
TOsclThreadId id;
int32 result = OsclThread::GetId(id);
if (result != OsclProcStatus::SUCCESS_ERROR)
OsclError::Leave(OsclErrSystemCallFailed);
return (uint32)id;
}
/**
// a static utility to tell whether the calling
// thread has any scheduler-- either Oscl scheduler
// or native scheduler.
*/
OSCL_EXPORT_REF bool PVThreadContext::ThreadHasScheduler()
{
if (OsclExecScheduler::Current() != NULL)
return true;
return false;
}