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