egl/egltest/endpointtestsuite/automated/tsrc/egltest_threadmonitor.cpp
author hgs
Fri, 30 Jul 2010 11:41:40 +0300
changeset 136 62bb7c97884c
permissions -rw-r--r--
201030_2
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
136
62bb7c97884c 201030_2
hgs
parents:
diff changeset
     1
/*
62bb7c97884c 201030_2
hgs
parents:
diff changeset
     2
* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
62bb7c97884c 201030_2
hgs
parents:
diff changeset
     3
* All rights reserved.
62bb7c97884c 201030_2
hgs
parents:
diff changeset
     4
* This component and the accompanying materials are made available
62bb7c97884c 201030_2
hgs
parents:
diff changeset
     5
* under the terms of "Eclipse Public License v1.0"
62bb7c97884c 201030_2
hgs
parents:
diff changeset
     6
* which accompanies this distribution, and is available
62bb7c97884c 201030_2
hgs
parents:
diff changeset
     7
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
62bb7c97884c 201030_2
hgs
parents:
diff changeset
     8
*
62bb7c97884c 201030_2
hgs
parents:
diff changeset
     9
* Initial Contributors:
62bb7c97884c 201030_2
hgs
parents:
diff changeset
    10
* Nokia Corporation - initial contribution.
62bb7c97884c 201030_2
hgs
parents:
diff changeset
    11
*
62bb7c97884c 201030_2
hgs
parents:
diff changeset
    12
* Contributors:
62bb7c97884c 201030_2
hgs
parents:
diff changeset
    13
*
62bb7c97884c 201030_2
hgs
parents:
diff changeset
    14
* Description: 
62bb7c97884c 201030_2
hgs
parents:
diff changeset
    15
*
62bb7c97884c 201030_2
hgs
parents:
diff changeset
    16
*/
62bb7c97884c 201030_2
hgs
parents:
diff changeset
    17
62bb7c97884c 201030_2
hgs
parents:
diff changeset
    18
62bb7c97884c 201030_2
hgs
parents:
diff changeset
    19
/**
62bb7c97884c 201030_2
hgs
parents:
diff changeset
    20
 @file
62bb7c97884c 201030_2
hgs
parents:
diff changeset
    21
 @test
62bb7c97884c 201030_2
hgs
parents:
diff changeset
    22
 @internalComponent - Internal Symbian test code
62bb7c97884c 201030_2
hgs
parents:
diff changeset
    23
*/
62bb7c97884c 201030_2
hgs
parents:
diff changeset
    24
62bb7c97884c 201030_2
hgs
parents:
diff changeset
    25
62bb7c97884c 201030_2
hgs
parents:
diff changeset
    26
#include <e32math.h>
62bb7c97884c 201030_2
hgs
parents:
diff changeset
    27
#include "egltest_threadmonitor.h"
62bb7c97884c 201030_2
hgs
parents:
diff changeset
    28
62bb7c97884c 201030_2
hgs
parents:
diff changeset
    29
62bb7c97884c 201030_2
hgs
parents:
diff changeset
    30
//CThreadMonitor creates a new monitor thread and instanciates a CThreadMonitorBackend object.
62bb7c97884c 201030_2
hgs
parents:
diff changeset
    31
//The thread monitor backend is constructed on the monitor thread's heap and only 
62bb7c97884c 201030_2
hgs
parents:
diff changeset
    32
//runs in that context. It creates a CThread instance for each thread that it needs
62bb7c97884c 201030_2
hgs
parents:
diff changeset
    33
//to monitor. The CThread instance reports back to the monitor backend when the
62bb7c97884c 201030_2
hgs
parents:
diff changeset
    34
//thread that it wraps has exitted. The backend is then responsible for deciding 
62bb7c97884c 201030_2
hgs
parents:
diff changeset
    35
//how to respond: If the exit type is a panic, it forwards that panic to all the 
62bb7c97884c 201030_2
hgs
parents:
diff changeset
    36
//other threads, then exits itself. Note: The controller thread MUST be at position
62bb7c97884c 201030_2
hgs
parents:
diff changeset
    37
//zero in the passed in array.
62bb7c97884c 201030_2
hgs
parents:
diff changeset
    38
class CThreadMonitorBackend : public CActive
62bb7c97884c 201030_2
hgs
parents:
diff changeset
    39
    {
62bb7c97884c 201030_2
hgs
parents:
diff changeset
    40
private:
62bb7c97884c 201030_2
hgs
parents:
diff changeset
    41
    class CThread : public CActive
62bb7c97884c 201030_2
hgs
parents:
diff changeset
    42
        {
62bb7c97884c 201030_2
hgs
parents:
diff changeset
    43
    public:
62bb7c97884c 201030_2
hgs
parents:
diff changeset
    44
        static CThread* NewL(const TThreadId& aThread, CThreadMonitorBackend& aMonitor);
62bb7c97884c 201030_2
hgs
parents:
diff changeset
    45
        ~CThread();
62bb7c97884c 201030_2
hgs
parents:
diff changeset
    46
        void Panic(TInt aExitReason, const TExitCategoryName& aExitCategory);
62bb7c97884c 201030_2
hgs
parents:
diff changeset
    47
        
62bb7c97884c 201030_2
hgs
parents:
diff changeset
    48
    private:
62bb7c97884c 201030_2
hgs
parents:
diff changeset
    49
        CThread(CThreadMonitorBackend& aMonitor);
62bb7c97884c 201030_2
hgs
parents:
diff changeset
    50
        void ConstructL(const TThreadId& aThread);
62bb7c97884c 201030_2
hgs
parents:
diff changeset
    51
        void RunL();
62bb7c97884c 201030_2
hgs
parents:
diff changeset
    52
        void DoCancel();
62bb7c97884c 201030_2
hgs
parents:
diff changeset
    53
    
62bb7c97884c 201030_2
hgs
parents:
diff changeset
    54
    private:
62bb7c97884c 201030_2
hgs
parents:
diff changeset
    55
        CThreadMonitorBackend& iMonitor;
62bb7c97884c 201030_2
hgs
parents:
diff changeset
    56
        RThread iThread;
62bb7c97884c 201030_2
hgs
parents:
diff changeset
    57
        };
62bb7c97884c 201030_2
hgs
parents:
diff changeset
    58
62bb7c97884c 201030_2
hgs
parents:
diff changeset
    59
public:
62bb7c97884c 201030_2
hgs
parents:
diff changeset
    60
    static CThreadMonitorBackend* NewL(const RArray<TThreadId>& aThreadsToMonitor, TRequestStatus*& aNotifyCancel);
62bb7c97884c 201030_2
hgs
parents:
diff changeset
    61
    ~CThreadMonitorBackend();
62bb7c97884c 201030_2
hgs
parents:
diff changeset
    62
    void StartMonitoring();
62bb7c97884c 201030_2
hgs
parents:
diff changeset
    63
    void ThreadExitted(CThread* aThread, TExitType aExitType, TInt aExitReason, const TExitCategoryName& aExitCategory);
62bb7c97884c 201030_2
hgs
parents:
diff changeset
    64
    
62bb7c97884c 201030_2
hgs
parents:
diff changeset
    65
private:
62bb7c97884c 201030_2
hgs
parents:
diff changeset
    66
    CThreadMonitorBackend(TRequestStatus*& aNotifyCancel);
62bb7c97884c 201030_2
hgs
parents:
diff changeset
    67
    void ConstructL(const RArray<TThreadId>& aThreadsToMonitor);
62bb7c97884c 201030_2
hgs
parents:
diff changeset
    68
    TBool ThreadIsController(CThread* aThread) const;
62bb7c97884c 201030_2
hgs
parents:
diff changeset
    69
    void RunL();
62bb7c97884c 201030_2
hgs
parents:
diff changeset
    70
    void DoCancel();
62bb7c97884c 201030_2
hgs
parents:
diff changeset
    71
    
62bb7c97884c 201030_2
hgs
parents:
diff changeset
    72
private:
62bb7c97884c 201030_2
hgs
parents:
diff changeset
    73
    RPointerArray<CThread> iThreads;
62bb7c97884c 201030_2
hgs
parents:
diff changeset
    74
    };
62bb7c97884c 201030_2
hgs
parents:
diff changeset
    75
62bb7c97884c 201030_2
hgs
parents:
diff changeset
    76
62bb7c97884c 201030_2
hgs
parents:
diff changeset
    77
//CThreadMonitor---------------------------------------------------------------
62bb7c97884c 201030_2
hgs
parents:
diff changeset
    78
62bb7c97884c 201030_2
hgs
parents:
diff changeset
    79
CThreadMonitor* CThreadMonitor::NewL(const RArray<TThreadId>& aThreadsToMonitor)
62bb7c97884c 201030_2
hgs
parents:
diff changeset
    80
    {
62bb7c97884c 201030_2
hgs
parents:
diff changeset
    81
    CThreadMonitor* self = new (ELeave) CThreadMonitor(aThreadsToMonitor);
62bb7c97884c 201030_2
hgs
parents:
diff changeset
    82
    CleanupStack::PushL(self);
62bb7c97884c 201030_2
hgs
parents:
diff changeset
    83
    self->ConstructL();
62bb7c97884c 201030_2
hgs
parents:
diff changeset
    84
    CleanupStack::Pop(self);
62bb7c97884c 201030_2
hgs
parents:
diff changeset
    85
    return self;
62bb7c97884c 201030_2
hgs
parents:
diff changeset
    86
    }
62bb7c97884c 201030_2
hgs
parents:
diff changeset
    87
62bb7c97884c 201030_2
hgs
parents:
diff changeset
    88
62bb7c97884c 201030_2
hgs
parents:
diff changeset
    89
CThreadMonitor::~CThreadMonitor()
62bb7c97884c 201030_2
hgs
parents:
diff changeset
    90
    {
62bb7c97884c 201030_2
hgs
parents:
diff changeset
    91
    //Tell the backend to stop monitoring.
62bb7c97884c 201030_2
hgs
parents:
diff changeset
    92
    iMonitor.RequestComplete(iNotifyCancel, KErrNone);
62bb7c97884c 201030_2
hgs
parents:
diff changeset
    93
    iMonitor.Close();
62bb7c97884c 201030_2
hgs
parents:
diff changeset
    94
    }
62bb7c97884c 201030_2
hgs
parents:
diff changeset
    95
62bb7c97884c 201030_2
hgs
parents:
diff changeset
    96
62bb7c97884c 201030_2
hgs
parents:
diff changeset
    97
CThreadMonitor::CThreadMonitor(const RArray<TThreadId>& aThreadsToMonitor) :
62bb7c97884c 201030_2
hgs
parents:
diff changeset
    98
    iThreadsToMonitor(aThreadsToMonitor)
62bb7c97884c 201030_2
hgs
parents:
diff changeset
    99
    {
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   100
    }
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   101
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   102
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   103
void CThreadMonitor::ConstructL()
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   104
    {
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   105
    const TInt KStackSize = 12000;
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   106
    const TInt KHeapMinSize = 16000;
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   107
    const TInt KHeapMaxSize = 1000000;
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   108
    
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   109
    TUint32 random = Math::Random();
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   110
    TName threadName;
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   111
    _LIT(KThreadNameFormat, "%S-%u");
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   112
    _LIT(KMonitorName, "EpThreadMonitor");
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   113
    threadName.Format(KThreadNameFormat, &KMonitorName, random);
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   114
    
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   115
    User::LeaveIfError(iMonitor.Create(threadName, MonitorThreadEntry, KStackSize, KHeapMinSize, KHeapMaxSize, this, EOwnerThread));
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   116
    TRequestStatus rendezvous;
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   117
    iMonitor.Rendezvous(rendezvous);
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   118
    iMonitor.Resume();
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   119
    User::WaitForRequest(rendezvous);
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   120
    User::LeaveIfError(rendezvous.Int());
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   121
    ASSERT(iNotifyCancel);
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   122
    }
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   123
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   124
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   125
TInt CThreadMonitor::MonitorThreadEntry(TAny* aSelf)
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   126
    {
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   127
    CThreadMonitor* self = static_cast<CThreadMonitor*>(aSelf);
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   128
    CTrapCleanup* cleanup = CTrapCleanup::New();
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   129
    
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   130
    TRAPD(err, MonitorThreadEntryL(self->iThreadsToMonitor, self->iNotifyCancel));
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   131
    __ASSERT_ALWAYS(err == KErrNone, User::Invariant());
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   132
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   133
    delete cleanup;
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   134
    return KErrNone;
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   135
    }
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   136
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   137
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   138
void CThreadMonitor::MonitorThreadEntryL(const RArray<TThreadId>& aThreadsToMonitor, TRequestStatus*& aNotifyCancel)
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   139
    {
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   140
    //Create active scheduler.
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   141
    CActiveScheduler* scheduler = new (ELeave) CActiveScheduler();
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   142
    CleanupStack::PushL(scheduler);
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   143
    CActiveScheduler::Install(scheduler);
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   144
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   145
    //Create the monitor and start monitoring.
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   146
    CThreadMonitorBackend* monitor = CThreadMonitorBackend::NewL(aThreadsToMonitor, aNotifyCancel);
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   147
    RThread().Rendezvous(KErrNone);
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   148
    monitor->StartMonitoring();
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   149
    delete monitor;
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   150
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   151
    //Clean up.
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   152
    CleanupStack::PopAndDestroy(scheduler);
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   153
    }
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   154
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   155
//-----------------------------------------------------------------------------
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   156
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   157
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   158
//CThreadMonitorBackend--------------------------------------------------------
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   159
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   160
CThreadMonitorBackend* CThreadMonitorBackend::NewL(const RArray<TThreadId>& aThreadsToMonitor, TRequestStatus*& aNotifyCancel)
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   161
    {
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   162
    CThreadMonitorBackend* self = new (ELeave) CThreadMonitorBackend(aNotifyCancel);
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   163
    CleanupStack::PushL(self);
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   164
    self->ConstructL(aThreadsToMonitor);
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   165
    CleanupStack::Pop(self);
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   166
    return self;
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   167
    }
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   168
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   169
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   170
CThreadMonitorBackend::CThreadMonitorBackend(TRequestStatus*& aNotifyCancel) :
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   171
    CActive(CActive::EPriorityStandard)
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   172
    {
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   173
    CActiveScheduler::Add(this);
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   174
    iStatus = KRequestPending;
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   175
    SetActive();
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   176
    
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   177
    //Pass the cancel TRequestStatus back to the controller thread.
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   178
    aNotifyCancel = &iStatus;
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   179
    }
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   180
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   181
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   182
void CThreadMonitorBackend::ConstructL(const RArray<TThreadId>& aThreadsToMonitor)
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   183
    {
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   184
    //Reserve the space up front so we can gaurantee that the append will not fail.
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   185
    //This way we don't need to use the cleanup stack to hold the new CThread while
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   186
    //we attempt to append.
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   187
    iThreads.ReserveL(aThreadsToMonitor.Count());
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   188
    for(TInt i=0; i < aThreadsToMonitor.Count(); i++)
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   189
        {
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   190
        iThreads.Append(CThread::NewL(aThreadsToMonitor[i], *this));
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   191
        }
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   192
    }
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   193
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   194
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   195
CThreadMonitorBackend::~CThreadMonitorBackend()
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   196
    {
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   197
    Cancel();
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   198
    iThreads.ResetAndDestroy();
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   199
    }
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   200
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   201
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   202
void CThreadMonitorBackend::StartMonitoring()
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   203
    {
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   204
    CActiveScheduler::Start();
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   205
    }
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   206
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   207
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   208
void CThreadMonitorBackend::ThreadExitted(CThread* aThread, TExitType aExitType, TInt aExitReason, const TExitCategoryName& aExitCategory)
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   209
    {
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   210
    //If a worker thread exits normally, do nothing.
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   211
    //If a worker thread panics, forward the panic to all other threads and stop active scheduler.
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   212
    //If the controller thread exits normally, stop active scheduler.
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   213
    //If the controller thread panics, forward the panic to all other threads and stop active scheduler.
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   214
    
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   215
    //Stop monitoring according to above.
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   216
    if(ThreadIsController(aThread) || aExitType == EExitPanic)
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   217
        {
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   218
        CActiveScheduler::Stop();
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   219
        }
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   220
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   221
    //Forward panic according to above. Second condition is for when controller times out.
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   222
    if(aExitType == EExitPanic || (ThreadIsController(aThread) && aExitType == EExitKill && aExitReason == KErrTimedOut))
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   223
        {
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   224
        for(TInt i=0; i < iThreads.Count(); i++)
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   225
            {
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   226
            iThreads[i]->Panic(aExitReason, aExitCategory);
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   227
            }
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   228
        }
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   229
    }
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   230
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   231
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   232
TBool CThreadMonitorBackend::ThreadIsController(CThread* aThread) const
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   233
    {
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   234
    //The controller thread must be at index zero in the passed in array.
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   235
    //Due to way we construct, we gaurantee that it is also at index zero in iThread.
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   236
    return (iThreads.Count() > 0) && (iThreads[0] == aThread);
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   237
    }
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   238
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   239
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   240
void CThreadMonitorBackend::RunL()
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   241
    {
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   242
    //The client has destructed the CThreadMonitor object, 
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   243
    //so stop the active scheduler so we exit the thread.
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   244
    CActiveScheduler::Stop();
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   245
    }
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   246
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   247
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   248
void CThreadMonitorBackend::DoCancel()
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   249
    {
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   250
    //Not ideal, but we should only get here if the thread that created 
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   251
    //the original ConitorThread panics, so it should be safe.
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   252
    TRequestStatus* status =&iStatus;
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   253
    User::RequestComplete(status, KErrCancel);
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   254
    }
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   255
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   256
//-----------------------------------------------------------------------------
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   257
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   258
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   259
//CThreadMonitorBackend::CThread-----------------------------------------------
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   260
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   261
CThreadMonitorBackend::CThread* CThreadMonitorBackend::CThread::NewL(const TThreadId& aThread, CThreadMonitorBackend& aMonitor)
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   262
    {
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   263
    CThread* self = new (ELeave) CThread(aMonitor);
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   264
    CleanupStack::PushL(self);
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   265
    self->ConstructL(aThread);
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   266
    CleanupStack::Pop(self);
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   267
    return self;
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   268
    }
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   269
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   270
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   271
CThreadMonitorBackend::CThread::CThread(CThreadMonitorBackend& aMonitor) :
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   272
    CActive(CActive::EPriorityStandard),
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   273
    iMonitor(aMonitor)
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   274
    {
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   275
    CActiveScheduler::Add(this);
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   276
    }
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   277
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   278
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   279
void CThreadMonitorBackend::CThread::ConstructL(const TThreadId& aThread)
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   280
    {
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   281
    User::LeaveIfError(iThread.Open(aThread, EOwnerThread));
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   282
    iThread.Logon(iStatus);
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   283
    SetActive();
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   284
    }
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   285
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   286
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   287
CThreadMonitorBackend::CThread::~CThread()
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   288
    {
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   289
    Cancel();
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   290
    iThread.Close();
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   291
    }
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   292
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   293
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   294
void CThreadMonitorBackend::CThread::Panic(TInt aExitReason, const TExitCategoryName& aExitCategory)
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   295
    {
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   296
    iThread.Panic(aExitCategory, aExitReason);
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   297
    }
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   298
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   299
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   300
void CThreadMonitorBackend::CThread::RunL()
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   301
    {
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   302
    //Inform the monitor backend that the thread exitted.
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   303
    TExitCategoryName category = iThread.ExitCategory();
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   304
    TInt reason = iThread.ExitReason();
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   305
    TExitType type = iThread.ExitType();
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   306
    iMonitor.ThreadExitted(this, type, reason, category);
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   307
    }
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   308
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   309
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   310
void CThreadMonitorBackend::CThread::DoCancel()
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   311
    {
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   312
    iThread.LogonCancel(iStatus);
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   313
    }
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   314
62bb7c97884c 201030_2
hgs
parents:
diff changeset
   315
//-----------------------------------------------------------------------------