Update contrib.
1 // Copyright (c) 2007-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".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
14 // Thread for reading and writing to a drive.
23 #ifndef __RWDRIVETHREAD_H__
24 #define __RWDRIVETHREAD_H__
26 #ifdef MSDC_MULTITHREADED
28 typedef void (*ProcessWriteCompleteFunc)(TUint8* aAddress, TAny* aPtr);
32 Class contains buffer for data with associated drive offset and length in bytes.
40 void SetPtr(TPtr8& aDes);
42 TPtr8 GetReadBuffer();
43 TPtr8 GetReadBuffer(TUint aLength, const TInt64& aOffset);
53 Class contains two buffers. Whilst one buffer is being read the
54 other buffer can be written to. The buffers should be accessed
55 by the buffer pointers iDescReadPtr and iDescWritePtr.
58 class TBlockDescBuffer
64 TInt MaxLength() const {return iDesc2.iBuf.MaxLength();}
65 TInt GetBufferNumber(const TPtr8* aBufferPtr) const;
66 void SetUpReadBuf(TPtr8& aDes1, TPtr8& aDes2);
69 /** Points to block descriptor containing buffer to read from */
70 TBlockDesc* iDescReadPtr;
71 /** Points to block descriptor containing buffer to write to */
72 TBlockDesc* iDescWritePtr;
75 /** Block descriptor for read/write operations */
77 /** Block descriptor for read/write operations */
83 Provides the common thread context used by CReadDriveThread and CWriteDriveThread
86 class CThreadContext : public CBase
89 static CThreadContext* NewL(const TDesC& aName,
90 TThreadFunction aThreadFunction,
96 void ConstructL(const TDesC& aName, TThreadFunction aThreadFunction, TAny* aOwner);
100 void Resume() {iThread.Resume();}
102 TInt MaxBufferLength() const {return iBuffer.MaxLength();}
103 TPtr8 GetReadBuffer();
104 TPtr8 GetReadBuffer(TInt aLength);
109 /** Used to tell thread which drive to use */
110 CMassStorageDrive* iDrive;
111 /** Used by the thread to return error code */
113 /** CS to regulate read/write buffer access */
114 RCriticalSection iCritSect;
116 /** buffer for reading and writing */
117 TBlockDescBuffer iBuffer;
125 Separate disk writer thread, used to implement OUT transfer double-buffering.
127 class CWriteDriveThread : public CBase
130 static CWriteDriveThread* NewL();
131 ~CWriteDriveThread();
138 TBlockDesc* GetReadDesc();
140 TInt WriteDriveData(CMassStorageDrive* aDrive, const TInt64& aOffset, TPtrC8& aDes, ProcessWriteCompleteFunc aFunc, TAny* aPtr);
142 TUint WriteBufferLength() const {return iThreadContext->iBuffer.iDescWritePtr->iBuf.Length();}
143 TUint ReadBufferLength() const {return iThreadContext->iBuffer.iDescReadPtr->iBuf.Length();}
145 TInt DeferredError() const {return iThreadContext->iError;}
146 void ClearDeferredError() {iThreadContext->iError = KErrNone;}
147 void WaitForWriteEmpty();
149 TBool IsRecentlyWritten(TInt64 aOffset, TInt aLength);
150 inline void SetCommandWrite10(TBool aIsWriteCommand) {iIsCommandWrite10 = aIsWriteCommand;};
153 static TInt ThreadFunction(TAny* aSelf);
157 /** Thread context */
158 CThreadContext* iThreadContext;
162 /** Semaphore for reading USB */
163 RSemaphore iProducerSem;
164 /** Semaphore for writing to drive */
165 RSemaphore iConsumerSem;
166 /* Call back to tell transport that 'transfer' was written and the corresponding buffer can be overwriiten (mainly for SC LDD) */
167 ProcessWriteCompleteFunc iCallback;
168 TAny* iCallbackParameter;
169 /* Flag set to true if the command is Write10. Used in Read10 to ignore pre-read if the previous command was Write10 */
170 TBool iIsCommandWrite10;
175 Separate disk reader thread, used to implement IN transfer double-buffering.
177 class CReadDriveThread : public CBase
180 static CReadDriveThread* NewL();
188 TBool ReadDriveData(CMassStorageDrive* aDrive, const TInt64& aOffset, TUint32 aLength, TBool aIgnoreCache);
192 static TInt ThreadFunction(TAny* aSelf);
193 TInt ReadFromDrive();
196 /** Thread context */
197 CThreadContext* iThreadContext;
201 TBool iThreadRunning;
205 //-----------------------------------------------
208 Swap the buffer which the read and write buffer pointers are pointing to.
210 inline void TBlockDescBuffer::SwapDesc()
212 TBlockDesc* const tmp = iDescReadPtr;
213 iDescReadPtr = iDescWritePtr;
217 inline TPtr8 TBlockDesc::GetReadBuffer()
219 return iBuf.LeftTPtr(iBuf.Length());
223 inline TPtr8 TBlockDesc::GetReadBuffer(TUint aLength, const TInt64& aOffset)
225 iByteOffset = aOffset;
227 iBuf.SetLength(aLength);
229 return GetReadBuffer();
232 //-----------------------------------------------
235 Returns the id of the buffer
237 @param bufferPtr pointer to the buffer.
238 @return returns the buffer ID or -1 if the buffer is not found.
240 inline TInt TBlockDescBuffer::GetBufferNumber(const TPtr8* aBufferPtr) const
243 if (aBufferPtr == &iDesc1.iBuf)
245 else if (aBufferPtr == &iDesc2.iBuf)
251 //-----------------------------------------------
253 inline TPtr8 CThreadContext::GetReadBuffer()
255 TInt len = iBuffer.iDescReadPtr->iBuf.Length();
256 return iBuffer.iDescReadPtr->iBuf.LeftTPtr(len);
260 inline TPtr8 CThreadContext::GetReadBuffer(TInt aLength)
262 iBuffer.iDescReadPtr->iBuf.SetLength(aLength);
263 return GetReadBuffer();
267 inline TPtrC8 CThreadContext::WriteBuf()
269 return iBuffer.iDescWritePtr->iBuf;
272 //-----------------------------------------------
274 inline TBlockDesc* CWriteDriveThread::GetReadDesc()
276 return iThreadContext->iBuffer.iDescReadPtr;
279 //-----------------------------------------------
281 #endif // MSDC_MULTITHREADED
283 #endif // __RWDRIVETHREAD_H__