1 /* ------------------------------------------------------------------
2 * Copyright (C) 1998-2009 PacketVideo
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
13 * express or implied.
14 * See the License for the specific language governing permissions
15 * and limitations under the License.
16 * -------------------------------------------------------------------
17 */
18
19
20 #include "osclconfig_proc.h"
21 #include "oscl_scheduler_threadcontext.h"
22 #include "oscl_scheduler.h"
23 #include "oscl_error.h"
24 #include "oscl_error_imp.h"
25 #include "oscl_thread.h"
26
PVThreadContext()27 OSCL_EXPORT_REF PVThreadContext::PVThreadContext()
28 {
29 iOpen = false;
30 iScheduler = NULL;
31 }
32
~PVThreadContext()33 OSCL_EXPORT_REF PVThreadContext::~PVThreadContext()
34 {
35 }
36
LeaveIfWrongThread(PVThreadContext & a)37 void PVThreadContext::LeaveIfWrongThread(PVThreadContext &a)
38 //static routine to verify thread context.
39 {
40 if (!a.IsSameThreadContext())
41 OsclError::Leave(OsclErrThreadContextIncorrect);
42 }
43
IsSameThreadContext()44 OSCL_EXPORT_REF bool PVThreadContext::IsSameThreadContext()
45 {
46 if (!iOpen)
47 return false;//unknown
48
49 //check calling thread context against
50 //this one.
51 TOsclThreadId id;
52 int32 result = OsclThread::GetId(id);
53 if (result != OsclProcStatus::SUCCESS_ERROR)
54 OsclError::Leave(OsclErrSystemCallFailed);
55
56 return OsclThread::CompareId(id, iThreadId);
57 }
58
EnterThreadContext()59 OSCL_EXPORT_REF void PVThreadContext::EnterThreadContext()
60 {
61 //Save thread ID.
62 int32 result = OsclThread::GetId(iThreadId);
63 if (result != OsclProcStatus::SUCCESS_ERROR)
64 OsclError::Leave(OsclErrSystemCallFailed);
65
66
67 //Set current thread scheduler.
68 iScheduler = OsclExecScheduler::GetScheduler();
69
70 if (!iScheduler)
71 {
72 //There must be a pv scheduler.
73 OsclError::Leave(OsclErrNotInstalled);
74 }
75
76 iOpen = true;
77 }
78
ExitThreadContext()79 OSCL_EXPORT_REF void PVThreadContext::ExitThreadContext()
80 {
81 iScheduler = NULL;
82 iOpen = false;
83 }
84
PendComplete(PVActiveBase * pvbase,int32 aReason,TPVThreadContext aCallingContext)85 void PVThreadContext::PendComplete(PVActiveBase *pvbase, int32 aReason, TPVThreadContext aCallingContext)
86 {
87 //request can be completed from any thread.
88 if (!iOpen)
89 OsclError::Leave(OsclErrInvalidState);//thread context unknown
90 //status can be anything but 'pending'
91 if (aReason == OSCL_REQUEST_PENDING)
92 OsclError::Leave(OsclErrInvalidState);//bad request status
93
94
95 //use PV scheduler mechanism to complete requests.
96
97 //first determine the calling context if possible.
98 if (aCallingContext == EPVThreadContext_Undetermined && IsSameThreadContext())
99 iScheduler->PendComplete(pvbase, aReason, EPVThreadContext_InThread);
100 else
101 iScheduler->PendComplete(pvbase, aReason, aCallingContext);
102
103 }
104
Id()105 OSCL_EXPORT_REF uint32 PVThreadContext::Id()
106 //static routine to get current context.
107 {
108 TOsclThreadId id;
109 int32 result = OsclThread::GetId(id);
110 if (result != OsclProcStatus::SUCCESS_ERROR)
111 OsclError::Leave(OsclErrSystemCallFailed);
112 return (uint32)id;
113 }
114
115 /**
116 // a static utility to tell whether the calling
117 // thread has any scheduler-- either Oscl scheduler
118 // or native scheduler.
119 */
ThreadHasScheduler()120 OSCL_EXPORT_REF bool PVThreadContext::ThreadHasScheduler()
121 {
122 if (OsclExecScheduler::Current() != NULL)
123 return true;
124 return false;
125 }
126
127
128