|
1 /* |
|
2 * Copyright (c) 2004 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * This component and the accompanying materials are made available |
|
5 * under the terms of "Eclipse Public License v1.0" |
|
6 * which accompanies this distribution, and is available |
|
7 * at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
8 * |
|
9 * Initial Contributors: |
|
10 * Nokia Corporation - initial contribution. |
|
11 * |
|
12 * Contributors: |
|
13 * |
|
14 * Description: |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 #include <e32def.h> |
|
20 #include <e32cmn.h> |
|
21 #include <arm.h> |
|
22 #include <kernel.h> |
|
23 #include <kern_priv.h> |
|
24 #include <nk_trace.h> |
|
25 |
|
26 #include "TrkKernelDriver.h" |
|
27 #include "TrkDriver.h" |
|
28 #include "TrkEventHandler.h" |
|
29 |
|
30 |
|
31 DMetroTrkEventHandler::DMetroTrkEventHandler() |
|
32 : DKernelEventHandler(EventHandler, this) |
|
33 { |
|
34 LOG_MSG("DMetroTrkEventHandler::DMetroTrkEventHandler()"); |
|
35 |
|
36 } |
|
37 |
|
38 |
|
39 TInt DMetroTrkEventHandler::Create(DLogicalDevice* aDevice, DLogicalChannel* aChannel, DThread* aClient) |
|
40 { |
|
41 LOG_MSG("DMetroTrkEventHandler::Create()"); |
|
42 |
|
43 TInt err; |
|
44 err = aDevice->Open(); |
|
45 if (err != KErrNone) |
|
46 return err; |
|
47 iDevice = aDevice; |
|
48 |
|
49 iChannel = aChannel; //Don't add ref the channel, since channel closes the event handler before it ever gets destroyed. |
|
50 |
|
51 err = aClient->Open(); |
|
52 if (err != KErrNone) |
|
53 return err; |
|
54 iClientThread = aClient; |
|
55 |
|
56 // Use a semaphore to protect our data structures from concurrent access. |
|
57 err = Kern::SemaphoreCreate(iLock, _L("TrkEventHandlerLock"), 1 /* Initial count */); |
|
58 |
|
59 if (err != KErrNone) |
|
60 return err; |
|
61 |
|
62 return Add(); |
|
63 } |
|
64 |
|
65 |
|
66 DMetroTrkEventHandler::~DMetroTrkEventHandler() |
|
67 { |
|
68 LOG_MSG("DMetroTrkEventHandler::~DMetroTrkEventHandler()"); |
|
69 |
|
70 if (iLock) |
|
71 iLock->Close(NULL); |
|
72 |
|
73 if (iDevice) |
|
74 iDevice->Close(NULL); |
|
75 |
|
76 if (iClientThread) |
|
77 Kern::SafeClose((DObject*&)iClientThread, NULL); |
|
78 |
|
79 } |
|
80 |
|
81 |
|
82 TInt DMetroTrkEventHandler::Start() |
|
83 { |
|
84 LOG_MSG("DMetroTrkEventHandler::Start()"); |
|
85 |
|
86 TInt r = KErrNone; |
|
87 iTracking = ETrue; |
|
88 return r; |
|
89 } |
|
90 |
|
91 |
|
92 TInt DMetroTrkEventHandler::Stop() |
|
93 { |
|
94 LOG_MSG("DMetroTrkEventHandler::Stop()"); |
|
95 |
|
96 //NKern::ThreadEnterCS(); |
|
97 //Kern::SemaphoreWait(*iLock); |
|
98 iTracking = EFalse; |
|
99 //Kern::SemaphoreSignal(*iLock); |
|
100 //NKern::ThreadLeaveCS(); |
|
101 |
|
102 return KErrNone; |
|
103 } |
|
104 |
|
105 |
|
106 TUint DMetroTrkEventHandler::EventHandler(TKernelEvent aType, TAny* a1, TAny* a2, TAny* aThis) |
|
107 { |
|
108 return ((DMetroTrkEventHandler*)aThis)->HandleEvent(aType, a1, a2); |
|
109 } |
|
110 |
|
111 TUint DMetroTrkEventHandler::HandleEvent(TKernelEvent aType, TAny* a1, TAny* a2) |
|
112 { |
|
113 if (iTracking) |
|
114 { |
|
115 iCounters[aType]++; |
|
116 switch (aType) |
|
117 { |
|
118 case EEventSwExc: |
|
119 { |
|
120 if (HandleSwException((TExcType)(TInt)a1)) |
|
121 return (TUint)DKernelEventHandler::EExcHandled; |
|
122 } |
|
123 |
|
124 case EEventHwExc: |
|
125 { |
|
126 if (HandleHwException((TArmExcInfo*)a1)) |
|
127 return (TUint)DKernelEventHandler::EExcHandled; |
|
128 } |
|
129 case EEventUpdateProcess: |
|
130 case EEventAddThread: |
|
131 case EEventUpdateThread: |
|
132 case EEventRemoveThread: |
|
133 case EEventNewChunk: |
|
134 case EEventDeleteChunk: |
|
135 //currently we don't handle any of these events; |
|
136 break; |
|
137 case EEventAddProcess: |
|
138 { |
|
139 AddProcess((DProcess*)a1, (DThread*)a2); |
|
140 break; |
|
141 } |
|
142 case EEventRemoveProcess: |
|
143 { |
|
144 RemoveProcess((DProcess*)a1); |
|
145 break; |
|
146 } |
|
147 case EEventStartThread: |
|
148 { |
|
149 StartThread((DThread*)a1); |
|
150 break; |
|
151 } |
|
152 // According to Symbian, the only way to catch panics in EKA2 is through this event. |
|
153 case EEventKillThread: |
|
154 { |
|
155 if (HandleEventKillThread((DThread*)a1)) |
|
156 return (TUint)DKernelEventHandler::EExcHandled; |
|
157 break; |
|
158 } |
|
159 case EEventAddLibrary: |
|
160 { |
|
161 AddLibrary((DLibrary*)a1, (DThread*)a2); |
|
162 break; |
|
163 } |
|
164 |
|
165 case EEventRemoveLibrary: |
|
166 { |
|
167 RemoveLibrary((DLibrary*)a1); |
|
168 break; |
|
169 } |
|
170 |
|
171 case EEventUserTrace: |
|
172 { |
|
173 HandleUserTrace((TText*)a1, (TInt)a2); |
|
174 break; |
|
175 } |
|
176 case EEventAddCodeSeg: |
|
177 { |
|
178 // |
|
179 // EventAddCodeSeg is not fired for all libs, for example, if a static lib is in ROM, |
|
180 // then you don't need get AddCodeSeg event for that lib. |
|
181 // |
|
182 //AddCodeSegment((DCodeSeg*)a1, (DProcess*)a2); |
|
183 break; |
|
184 } |
|
185 case EEventRemoveCodeSeg: |
|
186 { |
|
187 // RemoveCodeSegment((DCodeSeg*)a1, (DProcess*)a2); |
|
188 break; |
|
189 } |
|
190 default: |
|
191 break; |
|
192 } |
|
193 } |
|
194 return DKernelEventHandler::ERunNext; |
|
195 } |
|
196 |
|
197 // |
|
198 // DMetroTrkEventHandler::HandleEventKillThread |
|
199 // |
|
200 |
|
201 TBool DMetroTrkEventHandler::HandleEventKillThread(DThread* aThread) |
|
202 { |
|
203 LOG_MSG("DMetroTrkEventHandler::HandleEventKillThread()"); |
|
204 |
|
205 //NKern::ThreadEnterCS(); |
|
206 //Kern::SemaphoreWait(*iLock); |
|
207 |
|
208 TBool ret = ((DMetroTrkChannel*)iChannel)->HandleEventKillThread(aThread); |
|
209 |
|
210 //Kern::SemaphoreSignal(*iLock); |
|
211 //NKern::ThreadLeaveCS(); |
|
212 |
|
213 return ret; |
|
214 } |
|
215 |
|
216 |
|
217 // |
|
218 // DMetroTrkEventHandler::HandleSwException |
|
219 // |
|
220 |
|
221 TBool DMetroTrkEventHandler::HandleSwException(TExcType aExcType) |
|
222 { |
|
223 LOG_MSG("DMetroTrkEventHandler::HandleSwException()"); |
|
224 |
|
225 NKern::ThreadEnterCS(); |
|
226 Kern::SemaphoreWait(*iLock); |
|
227 |
|
228 TBool ret = ((DMetroTrkChannel*)iChannel)->HandleSwException(aExcType); |
|
229 |
|
230 Kern::SemaphoreSignal(*iLock); |
|
231 NKern::ThreadLeaveCS(); |
|
232 |
|
233 return ret; |
|
234 } |
|
235 |
|
236 // |
|
237 // DMetroTrkEventHandler::HandleHwException |
|
238 // |
|
239 |
|
240 TBool DMetroTrkEventHandler::HandleHwException(TArmExcInfo* aExcInfo) |
|
241 { |
|
242 LOG_MSG("DMetroTrkEventHandler::HandleHwException()"); |
|
243 |
|
244 TBool ret = EFalse; |
|
245 |
|
246 NKern::ThreadEnterCS(); |
|
247 Kern::SemaphoreWait(*iLock); |
|
248 |
|
249 if (aExcInfo) |
|
250 { |
|
251 ret = ((DMetroTrkChannel*)iChannel)->HandleHwException(aExcInfo); |
|
252 } |
|
253 |
|
254 Kern::SemaphoreSignal(*iLock); |
|
255 NKern::ThreadLeaveCS(); |
|
256 |
|
257 return ret; |
|
258 } |
|
259 |
|
260 // |
|
261 // DMetroTrkEventHandler::HandleUserTrace |
|
262 // |
|
263 TBool DMetroTrkEventHandler::HandleUserTrace(TText* aStr, TInt aLen) |
|
264 { |
|
265 LOG_MSG("DMetroTrkEventHandler::HandleUserTrace()"); |
|
266 TBool ret = EFalse; |
|
267 |
|
268 NKern::ThreadEnterCS(); |
|
269 Kern::SemaphoreWait(*iLock); |
|
270 |
|
271 if (aStr && aLen > 0) |
|
272 { |
|
273 ret = ((DMetroTrkChannel*)iChannel)->HandleUserTrace(aStr, aLen); |
|
274 } |
|
275 |
|
276 Kern::SemaphoreSignal(*iLock); |
|
277 NKern::ThreadLeaveCS(); |
|
278 |
|
279 return ret; |
|
280 } |
|
281 |
|
282 // |
|
283 // DMetroTrkEventHandler::AddProcess |
|
284 // |
|
285 void DMetroTrkEventHandler::AddProcess(DProcess* aProcess, DThread *aThread) |
|
286 { |
|
287 LOG_MSG("DMetroTrkEventHandler::AddProcess()"); |
|
288 |
|
289 NKern::ThreadEnterCS(); |
|
290 Kern::SemaphoreWait(*iLock); |
|
291 |
|
292 if (iChannel && aProcess && aThread) |
|
293 ((DMetroTrkChannel*)iChannel)->AddProcess(aProcess, aThread); |
|
294 |
|
295 Kern::SemaphoreSignal(*iLock); |
|
296 NKern::ThreadLeaveCS(); |
|
297 } |
|
298 |
|
299 // |
|
300 // DMetroTrkEventHandler::StartThread |
|
301 // |
|
302 void DMetroTrkEventHandler::StartThread(DThread *aThread) |
|
303 { |
|
304 LOG_MSG("DMetroTrkEventHandler::StartThread()"); |
|
305 |
|
306 NKern::ThreadEnterCS(); |
|
307 Kern::SemaphoreWait(*iLock); |
|
308 |
|
309 if (iChannel && aThread) |
|
310 ((DMetroTrkChannel*)iChannel)->StartThread(aThread); |
|
311 |
|
312 Kern::SemaphoreSignal(*iLock); |
|
313 NKern::ThreadLeaveCS(); |
|
314 } |
|
315 // |
|
316 // DMetroTrkEventHandler::RemoveProcess |
|
317 // |
|
318 void DMetroTrkEventHandler::RemoveProcess(DProcess *aProcess) |
|
319 { |
|
320 LOG_MSG("DMetroTrkEventHandler::RemoveProcess()"); |
|
321 |
|
322 NKern::ThreadEnterCS(); |
|
323 Kern::SemaphoreWait(*iLock); |
|
324 |
|
325 if (iChannel && aProcess) |
|
326 ((DMetroTrkChannel*)iChannel)->RemoveProcess(aProcess); |
|
327 |
|
328 Kern::SemaphoreSignal(*iLock); |
|
329 NKern::ThreadLeaveCS(); |
|
330 } |
|
331 |
|
332 // |
|
333 // DMetroTrkEventHandler::AddLibrary |
|
334 // |
|
335 void DMetroTrkEventHandler::AddLibrary(DLibrary *aLibrary, DThread *aThread) |
|
336 { |
|
337 LOG_MSG("DMetroTrkEventHandler::AddLibrary()"); |
|
338 |
|
339 NKern::ThreadEnterCS(); |
|
340 Kern::SemaphoreWait(*iLock); |
|
341 |
|
342 if (iChannel && aLibrary) |
|
343 ((DMetroTrkChannel*)iChannel)->AddLibrary(aLibrary, aThread); |
|
344 |
|
345 Kern::SemaphoreSignal(*iLock); |
|
346 NKern::ThreadLeaveCS(); |
|
347 } |
|
348 |
|
349 // |
|
350 // DMetroTrkEventHandler::RemoveLibrary |
|
351 // |
|
352 void DMetroTrkEventHandler::RemoveLibrary(DLibrary *aLibrary) |
|
353 { |
|
354 LOG_MSG("DMetroTrkEventHandler::RemoveLibrary()"); |
|
355 |
|
356 NKern::ThreadEnterCS(); |
|
357 Kern::SemaphoreWait(*iLock); |
|
358 |
|
359 if (iChannel && aLibrary) |
|
360 ((DMetroTrkChannel*)iChannel)->RemoveLibrary(aLibrary); |
|
361 |
|
362 Kern::SemaphoreSignal(*iLock); |
|
363 NKern::ThreadLeaveCS(); |
|
364 } |
|
365 |
|
366 // |
|
367 // DMetroTrkEventHandler::AddCodeSegment |
|
368 // |
|
369 void DMetroTrkEventHandler::AddCodeSegment(DCodeSeg *aCodeSeg, DProcess *aProcess) |
|
370 { |
|
371 LOG_MSG("DMetroTrkEventHandler::AddCodeSegment()"); |
|
372 |
|
373 NKern::ThreadEnterCS(); |
|
374 Kern::SemaphoreWait(*iLock); |
|
375 |
|
376 if (iChannel && aCodeSeg && aProcess) |
|
377 ((DMetroTrkChannel*)iChannel)->AddCodeSegment(aCodeSeg, aProcess); |
|
378 |
|
379 Kern::SemaphoreSignal(*iLock); |
|
380 NKern::ThreadLeaveCS(); |
|
381 } |
|
382 |
|
383 // |
|
384 // DMetroTrkEventHandler::RemoveCodeSegment |
|
385 // |
|
386 void DMetroTrkEventHandler::RemoveCodeSegment(DCodeSeg *aCodeSeg, DProcess *aProcess) |
|
387 { |
|
388 LOG_MSG("DMetroTrkEventHandler::RemoveCodeSegment()"); |
|
389 |
|
390 NKern::ThreadEnterCS(); |
|
391 Kern::SemaphoreWait(*iLock); |
|
392 |
|
393 if (iChannel && aCodeSeg && aProcess) |
|
394 ((DMetroTrkChannel*)iChannel)->RemoveCodeSegment(aCodeSeg, aProcess); |
|
395 |
|
396 Kern::SemaphoreSignal(*iLock); |
|
397 NKern::ThreadLeaveCS(); |
|
398 } |