userlibandfileserver/fileserver/sfile/sf_disk.cpp
changeset 0 a41df078684a
equal deleted inserted replaced
-1:000000000000 0:a41df078684a
       
     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