|
1 // Copyright (c) 1995-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
2 // All rights reserved. |
|
3 // This component and the accompanying materials are made available |
|
4 // under the terms of "Eclipse Public License v1.0" |
|
5 // which accompanies this distribution, and is available |
|
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // |
|
15 |
|
16 #include "openwfcthreadmanager.h" |
|
17 #include "openwfcjobmanager.h" |
|
18 |
|
19 |
|
20 COpenWfcMonitorThread::COpenWfcMonitorThread(COpenWfcJobManger& aManager): |
|
21 iEndThread(EFalse), |
|
22 iManager(aManager) |
|
23 { |
|
24 |
|
25 } |
|
26 |
|
27 COpenWfcMonitorThread::~COpenWfcMonitorThread() |
|
28 { |
|
29 EndThread(); |
|
30 TRequestStatus threadDies = KErrNone; |
|
31 iThread.Resume(); |
|
32 iThread.Logon(threadDies); |
|
33 if (iThread.ExitType() == EExitPending || |
|
34 threadDies != KRequestPending) |
|
35 { |
|
36 User::WaitForRequest(threadDies); |
|
37 } |
|
38 iThread.Close(); |
|
39 iSemaphore.Close(); |
|
40 } |
|
41 |
|
42 void COpenWfcMonitorThread::ConstructL(TInt aScreenNumber) |
|
43 { |
|
44 TBuf <255> threadManagerName; |
|
45 /* |
|
46 * At a given instant in time, one screen can have at most one monitor |
|
47 * thread. Test code will, for a given screen, destroy and re-create |
|
48 * the monitor thread. |
|
49 * |
|
50 * At appears that the thread, once killed off, still lingers in |
|
51 * the OS for a short time. The newly created thread fails to create |
|
52 * if it shares the same name as the one that was killed but still is |
|
53 * lingering around. |
|
54 * |
|
55 * A unique name is needed. This is guaranteed by using a thread name |
|
56 * which includes a microsecond counter. This counter wraps every hour, |
|
57 * roughly. This is comfortably outside the race condition above. |
|
58 * |
|
59 * To make debugging easier, we also include the screen number in |
|
60 * the thread name. |
|
61 * |
|
62 * Thus, the thread name is: |
|
63 * WFCMonitorThread_<ScreenNumber>_<MicrosecondCounter> |
|
64 */ |
|
65 _LIT(KThreadName, "WFCMonitorThread_%d_%d"); |
|
66 TTime now; |
|
67 now.UniversalTime(); |
|
68 TInt microseconds = I64LOW(now.Int64()); |
|
69 threadManagerName.Format(KThreadName, aScreenNumber, microseconds); |
|
70 |
|
71 User::LeaveIfError(iThread.Create(threadManagerName, |
|
72 static_cast<TThreadFunction>(&COpenWfcMonitorThread::Main), |
|
73 KDefaultStackSize, |
|
74 NULL, |
|
75 this, |
|
76 EOwnerProcess)); |
|
77 iThread.SetPriority(EPriorityNormal); |
|
78 User::LeaveIfError(iSemaphore.CreateLocal(0)); |
|
79 Start(); |
|
80 } |
|
81 |
|
82 COpenWfcMonitorThread* COpenWfcMonitorThread::NewLC(TInt aNumber, COpenWfcJobManger& aManager) |
|
83 { |
|
84 COpenWfcMonitorThread* self = new(ELeave) COpenWfcMonitorThread(aManager); |
|
85 CleanupStack::PushL(self); |
|
86 self->ConstructL(aNumber); |
|
87 return(self); |
|
88 } |
|
89 |
|
90 COpenWfcMonitorThread* COpenWfcMonitorThread::NewL(TInt aNumber, COpenWfcJobManger& aManager) |
|
91 { |
|
92 COpenWfcMonitorThread* self = COpenWfcMonitorThread::NewLC(aNumber, aManager); |
|
93 CleanupStack::Pop(self); |
|
94 return self; |
|
95 } |
|
96 |
|
97 TInt COpenWfcMonitorThread::Main(TAny *aSelf) |
|
98 { |
|
99 COpenWfcMonitorThread* self = static_cast<COpenWfcMonitorThread*>(aSelf); |
|
100 return self->Run(); |
|
101 } |
|
102 |
|
103 void COpenWfcMonitorThread::Start() |
|
104 { |
|
105 iThread.Rendezvous(iThreadStatus); |
|
106 iThread.Resume(); |
|
107 User::WaitForRequest(iThreadStatus); |
|
108 } |
|
109 |
|
110 void COpenWfcMonitorThread::Resume() |
|
111 { |
|
112 iThread.Resume(); |
|
113 } |
|
114 |
|
115 void COpenWfcMonitorThread::EndThread() |
|
116 { |
|
117 iSemaphore.Signal(); |
|
118 iEndThread = ETrue; |
|
119 } |
|
120 |
|
121 void COpenWfcMonitorThread::Suspend() |
|
122 { |
|
123 iThread.Suspend(); |
|
124 } |
|
125 |
|
126 void COpenWfcMonitorThread::Signal() |
|
127 { |
|
128 iSemaphore.Signal(); |
|
129 } |
|
130 |
|
131 TInt COpenWfcMonitorThread::Run() |
|
132 { |
|
133 RThread::Rendezvous(KErrNone); |
|
134 JQLOG(("** START * COpenWfcMonitorThread::Run()")); |
|
135 while(!iEndThread) |
|
136 { |
|
137 JQLOG(("** WAIT FOR SIGNAL * CCOpenwfcMonitorThread::Run()")); |
|
138 iSemaphore.Wait(); |
|
139 |
|
140 if (!iEndThread) |
|
141 { |
|
142 iManager.DoExecuteJob(); |
|
143 } |
|
144 } |
|
145 |
|
146 /* Release any use of EGL by this thread. */ |
|
147 eglReleaseThread(); |
|
148 |
|
149 JQLOG(("** EXIT * COpenWfcMonitorThread::Run()")); |
|
150 return KErrNone; |
|
151 } |