os/kernelhwsrv/userlibandfileserver/fileserver/sfile/sf_disk.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 // Copyright (c) 1998-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 the License "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 // f32\sfile\sf_disk.cpp
    15 // 
    16 //
    17 
    18 #include "sf_std.h"
    19 
    20 #if defined(_LOCKABLE_MEDIA)
    21 
    22 LOCAL_C TInt DelayedWriter(TAny *aPtr);
    23 LOCAL_C void DelayedWriterL(const TDelayedWriter *aDW);
    24 
    25 
    26 EXPORT_C void WriteToDisk(const TDesC& aFileName, const TDesC8& aBuf)
    27 // 
    28 // Launches as separate thread that writes the contents of the pbus pswd
    29 // store to disk.  It is possible that this function will be called again
    30 // before the thread has finished writing.  In that case, a new thread
    31 // will be created and it will wait on the global DelayedWriteSem semaphore.
    32 // 
    33 	{
    34 	static TInt32 ctr = 0x00000000;				// ctr to create unique thd names
    35 	
    36 	__PRINT(_L("WriteToDisk"));
    37 	__PRINT1(_L("wtd:afn%S"), &aFileName);
    38 
    39 	TDelayedWriterInit dwi;
    40 	dwi.iFileName = &aFileName;
    41 	dwi.iData = &aBuf;
    42 
    43 	// Create local semaphore this thread can wait on until the child thread has
    44 	// made copies of the file name and the store data.
    45 
    46 	__PRINT(_L("wtd:cr sem"));
    47 	TBuf<3 + 8> semName;
    48 	semName.Format(_L("dws%08x"), ctr++);
    49 	dwi.iSemName = &semName;
    50 	RSemaphore svrSem;
    51 	if (svrSem.CreateGlobal(semName, 0) != KErrNone)
    52 		return;
    53 
    54 	// Spin off a thread with a unique name.
    55 
    56 	__PRINT(_L("wtd:cr thd"));
    57 	TName nm;
    58 	nm.Format(_L("dw%08x"), ctr);
    59 	RThread t;
    60 	TInt hminsz = Max(KHeapMinSize, aFileName.Length() + aBuf.Length() + 1024);
    61 	if (t.Create(
    62 		nm, DelayedWriter, KDefaultStackSize,
    63 		hminsz /* aHeapMinSize */, hminsz /* aHeapMaxSize */, &dwi) == KErrNone)
    64 		{
    65 		__PRINT(_L("wtd:set pri"));
    66 		t.SetPriority(EPriorityMuchLess);		// run as low priority task
    67 		__PRINT(_L("wtd:res"));
    68 		t.Resume();
    69 		__PRINT(_L("wtd:wait"));
    70 		svrSem.Wait();
    71 		__PRINT(_L("wtd:cls thd"));
    72 		t.Close();								// get rid of our handle
    73 		}
    74 	
    75 	__PRINT(_L("wtd:cls sem"));
    76 	svrSem.Close();
    77 	}
    78 
    79 
    80 LOCAL_D TInt DelayedWriter(TAny *aPtr)
    81 //
    82 // Main thread function for thread that is spun off from WriteToDisk().
    83 // After local copies of the data have been allocated (or failed), tell
    84 // the server to continue.
    85 // 
    86 	{
    87 	__PRINT(_L("DelayedWriter"));
    88 
    89 	User::SetCritical(User::ESystemCritical);
    90 
    91 	TInt r;
    92 
    93 	TDelayedWriterInit *dwi = (TDelayedWriterInit *) aPtr;
    94 	RSemaphore svrSem;							// signal svr when data copied
    95 	CTrapCleanup *th = NULL;					// thread trap handler
    96 	TDelayedWriter *dw = NULL;					// thread copy of data
    97 	RSemaphore queueSem;						// queued delayed write threads
    98 
    99 	// Allocate a trap handler.
   100 	__PRINT(_L("dlw:alc tp"));
   101 	if ((th = CTrapCleanup::New()) == NULL)
   102 		{
   103 		r = KErrNoMemory;
   104 		goto cleanup;
   105 		}
   106 
   107 	// Make copies of the filename and store data.
   108 	__PRINT(_L("dlw:cp dat"));
   109 	TRAP(r, dw = TDelayedWriter::NewL(dwi));
   110 	if (r != KErrNone)
   111 		goto cleanup;
   112 	
   113 	// Tell file server made local copies of data and so can continue.
   114 	__PRINT(_L("dlw:sg cp dat"));
   115 	if ((r = svrSem.OpenGlobal(*dwi->iSemName)) != KErrNone)
   116 		goto cleanup;
   117 	svrSem.Signal();
   118 
   119 	// Wait for the other store threads to finish.
   120 	__PRINT(_L("dlw:wait"));
   121 	if ((r = queueSem.OpenGlobal(_L("dwsem"))) != KErrNone)
   122 		goto cleanup;
   123 	queueSem.Wait();
   124 
   125 	// Write the data and signal the global semaphore so follow up threads can run.
   126 	__PRINT(_L("dlw:wrt"));
   127 	TRAP(r, DelayedWriterL(dw));
   128 	__PRINT1(_L("dlw:wrt r = %d"), r);
   129 	queueSem.Signal();
   130 
   131 cleanup:										// free any opened resources
   132 	__PRINT(_L("dlw:cln"));
   133 	svrSem.Close();
   134 	delete th;
   135 	delete dw;
   136 	queueSem.Close();
   137 
   138 	return KErrNone;
   139 	}
   140 
   141 
   142 LOCAL_D void DelayedWriterL(const TDelayedWriter *aDW)
   143 //
   144 // Replace any existing store file; write data and set file as hidden and system.
   145 //
   146 	{
   147 	__PRINT(_L("DelayedWriterL"));
   148 
   149 	RFs fs;										// connect to the file server
   150 	CleanupClosePushL(fs);
   151 	User::LeaveIfError(fs.Connect());
   152 
   153 	RFile f;									// replace any existing file
   154 	CleanupClosePushL(f);
   155 
   156 	__PRINT(_L("dlw: opn"));
   157 
   158 	// Create the directory if it doesn't already exist
   159 	TInt r;
   160 	r = fs.MkDirAll(*aDW->iFileName);
   161 	if (r != KErrNone && r != KErrAlreadyExists)
   162 		{
   163 		__PRINT(_L("dlw: MkDirAll err"));
   164 		User::Leave(r);
   165 		}
   166 
   167 	User::LeaveIfError(f.Replace(fs, *aDW->iFileName, EFileShareExclusive | EFileStream | EFileWrite));
   168 	__PRINT(_L("dlw: wrt"));
   169 	User::LeaveIfError(f.Write(*aDW->iData));
   170 	__PRINT(_L("dlw: sat"));
   171 #ifndef __WINS__								// cannot replace hidden | system file in WINS.
   172 	User::LeaveIfError(f.SetAtt(KEntryAttHidden | KEntryAttSystem, 0x00000000));
   173 #endif
   174 	__PRINT(_L("dlw: dst"));
   175 	CleanupStack::PopAndDestroy(2);				// f, fs
   176 	}
   177 
   178 //
   179 // TDelayedWriter
   180 // 
   181 
   182 TDelayedWriter *TDelayedWriter::NewL(const TDelayedWriterInit *dwi)
   183 //
   184 // static
   185 // Allocates a TDelayedWriter structure on the thread's heap that is used to
   186 // persist the data that the writer thread will need during its lifetime.
   187 // 
   188 	{
   189 	__PRINT(_L("TDelayedWriter::NewL"));
   190 
   191 	TDelayedWriter *self = new(ELeave) TDelayedWriter();
   192 	CleanupStack::PushL(self);
   193 	self->ConstructL(dwi);
   194 	CleanupStack::Pop();						// self
   195 	return self;
   196 	}
   197 
   198 
   199 TDelayedWriter::TDelayedWriter()
   200 	{
   201 	__PRINT(_L("TDelayedWriter::TDelayedWriter"));
   202 
   203 	// empty.
   204 	}
   205 
   206 
   207 void TDelayedWriter::ConstructL(const TDelayedWriterInit *dwi)
   208 //
   209 // 2y initialisation.  Makes own copy of filename and data.
   210 // Fields are not popped onto CleanupStack because will be deleted in dtor
   211 // 
   212 	{
   213 	__PRINT(_L("TDelayedWriter::ConstructL"));
   214 
   215 	iFileName = dwi->iFileName->AllocL();
   216 	iData = dwi->iData->AllocL();
   217 	}
   218 
   219 TDelayedWriter::~TDelayedWriter()
   220 //
   221 // dtor - frees filename and store data that was allocated in ConstructL().
   222 //
   223 	{
   224 	__PRINT(_L("TDelayedWriter::~TDelayedWriter"));
   225 
   226 	delete iFileName;							// alloc in ConstructL()
   227 	delete iData;								// alloc in server
   228 	}
   229 
   230 #else
   231 
   232 EXPORT_C void WriteToDisk(const TDesC& /*aFileName*/, const TDesC8& /*aBuf*/)
   233 //
   234 //
   235 //
   236 	{}
   237 
   238 #endif