sl@0: // Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of the License "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // sl@0: sl@0: #include "t_property.h" sl@0: sl@0: class CPropBroadcastSlave : public CBase sl@0: { sl@0: public: sl@0: static TInt LoopThreadEntry(TAny*); sl@0: sl@0: CPropBroadcastSlave(CPropBroadcast* aProg, TUid aCategory, TUint aMasterKey, TUint aSlaveKey); sl@0: void Create(TThreadPriority); sl@0: void Delete(); sl@0: void Loop(); sl@0: sl@0: CPropBroadcast* iProg; sl@0: TUid iCategory; sl@0: TUint iMasterKey; sl@0: TUint iSlaveKey; sl@0: sl@0: RProperty iProp; sl@0: RThread iThread; sl@0: TRequestStatus iStatus; sl@0: sl@0: CPropBroadcastSlave* iNext; sl@0: }; sl@0: sl@0: sl@0: sl@0: CPropBroadcastSlave::CPropBroadcastSlave(CPropBroadcast* aProg, TUid aCategory, TUint aMasterKey, TUint aSlaveKey) : sl@0: iProg(aProg), iCategory(aCategory), iMasterKey(aMasterKey), iSlaveKey(aSlaveKey) sl@0: { sl@0: } sl@0: sl@0: void CPropBroadcastSlave::Create(TThreadPriority aPrio) sl@0: { sl@0: TInt r = iProp.Define(iCategory, iSlaveKey, RProperty::EInt, KPassPolicy, KPassPolicy); sl@0: TF_ERROR_PROG(iProg, r, r == KErrNone); sl@0: r = iProp.Attach(iCategory, iSlaveKey); sl@0: TF_ERROR_PROG(iProg, r, r == KErrNone); sl@0: sl@0: r = iThread.Create(KNullDesC, LoopThreadEntry, 0x2000, NULL, this); sl@0: TF_ERROR_PROG(iProg, r, r == KErrNone); sl@0: iThread.Logon(iStatus); sl@0: iThread.SetPriority(aPrio); sl@0: iThread.Resume(); sl@0: } sl@0: sl@0: void CPropBroadcastSlave::Delete() sl@0: { sl@0: iThread.Kill(EExitKill); sl@0: iThread.Close(); sl@0: User::WaitForRequest(iStatus); sl@0: TF_ERROR_PROG(iProg, iStatus.Int(), iStatus.Int() == EExitKill); sl@0: sl@0: TInt r = iProp.Delete(iCategory, iSlaveKey); sl@0: TF_ERROR_PROG(iProg, r, r == KErrNone); sl@0: iProp.Close(); sl@0: sl@0: delete this; sl@0: } sl@0: sl@0: TInt CPropBroadcastSlave::LoopThreadEntry(TAny* ptr) sl@0: { sl@0: CPropBroadcastSlave* self = (CPropBroadcastSlave*) ptr; sl@0: self->Loop(); sl@0: return KErrNone; sl@0: } sl@0: sl@0: void CPropBroadcastSlave::Loop() sl@0: { sl@0: RProperty mProp; sl@0: TInt r = mProp.Attach(iCategory, iMasterKey, EOwnerThread); sl@0: TF_ERROR_PROG(iProg, r, r == KErrNone); sl@0: sl@0: RProperty sProp; sl@0: r = sProp.Attach(iCategory, iSlaveKey, EOwnerThread); sl@0: TF_ERROR_PROG(iProg, r, r == KErrNone); sl@0: sl@0: TInt value = 1; sl@0: for(;;) sl@0: { sl@0: TRequestStatus status; sl@0: mProp.Subscribe(status); sl@0: sl@0: r = sProp.Set(value); sl@0: TF_ERROR_PROG(iProg, r, r == KErrNone); sl@0: sl@0: User::WaitForRequest(status); sl@0: sl@0: r = mProp.Get(value); sl@0: TF_ERROR_PROG(iProg, r, r == KErrNone); sl@0: } sl@0: } sl@0: sl@0: _LIT(KPropBroadcastName, "RProperty Broadcast"); sl@0: sl@0: CPropBroadcast::CPropBroadcast(TUid aCategory, TUint aMasterKey, sl@0: TUint aSlaveKeySlot, TUint aSlaveCount, TUint aFirstHighPriority) : sl@0: CTestProgram(KPropBroadcastName), iCategory(aCategory), iMasterKey(aMasterKey), sl@0: iSlaveKeySlot(aSlaveKeySlot), iSlaveCount(aSlaveCount), iFirstHighPriority(aFirstHighPriority) sl@0: { sl@0: } sl@0: sl@0: sl@0: void CPropBroadcast::Run(TUint aCount) sl@0: { sl@0: RProperty mProp; sl@0: TInt r = mProp.Define(iCategory, iMasterKey, RProperty::EInt, KPassPolicy, KPassPolicy); sl@0: TF_ERROR(r, r == KErrNone); sl@0: r = mProp.Attach(iCategory, iMasterKey); sl@0: TF_ERROR(r, r == KErrNone); sl@0: sl@0: for (TUint j = 0; j < iSlaveCount; ++j) sl@0: { sl@0: CPropBroadcastSlave* slave = new CPropBroadcastSlave(this, iCategory, iMasterKey, iSlaveKeySlot + j); sl@0: slave->Create((j < iFirstHighPriority) ? EPriorityLess : EPriorityMore); sl@0: sl@0: slave->iNext = iSlaveList; sl@0: iSlaveList = slave; sl@0: } sl@0: sl@0: for (TUint i = 1; i < aCount; ++i) sl@0: { sl@0: CPropBroadcastSlave* slave = iSlaveList; sl@0: while (slave) sl@0: { sl@0: TRequestStatus status; sl@0: slave->iProp.Subscribe(status); sl@0: TInt value; sl@0: r = slave->iProp.Get(value); sl@0: TF_ERROR(r, r == KErrNone); sl@0: if (value == (TInt) i) sl@0: { sl@0: slave->iProp.Cancel(); sl@0: } sl@0: User::WaitForRequest(status); sl@0: TF_ERROR(status.Int(), (status.Int() == KErrCancel) || (status.Int() == KErrNone)); sl@0: r = slave->iProp.Get(value); sl@0: TF_ERROR(r, r == KErrNone); sl@0: TF_ERROR(value, value == (TInt) i); sl@0: slave = slave->iNext; sl@0: } sl@0: mProp.Set(i + 1); sl@0: } sl@0: sl@0: for (;;) sl@0: { sl@0: CPropBroadcastSlave* slave = iSlaveList; sl@0: if (slave == NULL) break; sl@0: iSlaveList = slave->iNext; sl@0: slave->Delete(); sl@0: } sl@0: sl@0: mProp.Delete(iCategory, iMasterKey); sl@0: mProp.Close(); sl@0: }