kernel/eka/include/drivers/dpipe.h
changeset 0 a41df078684a
equal deleted inserted replaced
-1:000000000000 0:a41df078684a
       
     1 // Copyright (c) 2006-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 //
       
    15 
       
    16 
       
    17 
       
    18 
       
    19 #ifndef __DPIPE_H__
       
    20 #define __DPIPE_H__
       
    21 
       
    22 #define _TEST__
       
    23 
       
    24 #if !defined(__KERNEL_H__)
       
    25 #include <kernel/kernel.h>
       
    26 #endif
       
    27 
       
    28 #include <rpipe.h>
       
    29 
       
    30 const TInt  KIdBase		= 0x0;
       
    31 
       
    32 class DPipe;
       
    33 
       
    34 class DPipeDevice : public DLogicalDevice
       
    35 /**
       
    36 The factory class is derived from Dlogical device. The user side calls 
       
    37 User::LoadLogicalDevice() to load the LDD dll and create the LDD 
       
    38 factory object in the kernel heap.
       
    39 @internalTechnology
       
    40 */
       
    41 {
       
    42 public:
       
    43 	/**
       
    44 	 Set the version number
       
    45 	 */
       
    46     DPipeDevice();
       
    47 
       
    48     ~DPipeDevice();
       
    49 
       
    50     // Inherited from DLogicalDevice
       
    51 	/**
       
    52 	 Second stage constructor and at least set a name for the 
       
    53 	 driver object.
       
    54 	 */
       
    55     virtual TInt Install();
       
    56 
       
    57 
       
    58     virtual void GetCaps(TDes8& aDes) const;
       
    59 
       
    60 	/**
       
    61 	 Called by the Kernel's Device driver framework to create a logical
       
    62 	 Channel. This called in the context of the user thread. which requested
       
    63 	 the creation of the logical channel.It checks if maximum pipe creation 
       
    64 	 has reached before creating a new Kernel pipe object.
       
    65 	 @param aChannel Set to point to the created logical channel
       
    66 
       
    67 	 @return KErrNone if successful, otherwise system wide error codes.
       
    68 	 */
       
    69     virtual TInt Create(DLogicalChannelBase*& aChannel);
       
    70 
       
    71 	
       
    72 	/**
       
    73 	 Called by the Logical channel instance to create DPipe  and
       
    74 	 associate itself.
       
    75 	 */
       
    76 	TInt  CreatePipe(const TDesC& aName, TInt aSize, DPipe*& aPipe, TAny* aCapCheck = NULL);
       
    77 
       
    78 	DPipe* CreatePipe(TInt aSize);
       
    79 	
       
    80 	DPipe* FindNamedPipe(const TDesC* aName);
       
    81 
       
    82 	DPipe* FindUnnamedPipe(const TInt aId);
       
    83 
       
    84 	TInt Destroy(const TDesC* aName);
       
    85 
       
    86 	TInt Close(TInt aId);
       
    87 	
       
    88 	
       
    89 	inline DMutex& Mutex()
       
    90 		{
       
    91 		return *iMutex;
       
    92 		}
       
    93 
       
    94 	inline void Wait()
       
    95 		{
       
    96 		Kern::MutexWait(*iMutex);
       
    97 		}
       
    98 	
       
    99 	inline void Signal()
       
   100 		{
       
   101 		Kern::MutexSignal(*iMutex);
       
   102 		}
       
   103   
       
   104  private:
       
   105  	TInt GenerateId();
       
   106 	
       
   107 	TInt AddPipe(DPipe* aObj);
       
   108 	
       
   109     void RemovePipe(DPipe** aObj);
       
   110     
       
   111     
       
   112 private:
       
   113 	 //! Represents the Data in a pipe.
       
   114 	DPipe **iDpipes;
       
   115 	
       
   116 	DMutex *iMutex;	
       
   117 	
       
   118 	TInt iAllocated;
       
   119 	
       
   120 	TInt iCount;
       
   121 	
       
   122     TInt iIdindex;
       
   123 
       
   124 };
       
   125 
       
   126 
       
   127 
       
   128 class DPipeChannel : public DLogicalChannelBase
       
   129 /**
       
   130 DPipe Channel provides the Kernel interface to the DPipe. The request from the RPipe handler 
       
   131 in the context of user thread, is transfered to DPipeChannel class. This is the interface 
       
   132 between the DPipe kernel object and the user request through RPipe handler. 
       
   133 
       
   134 @internalTechnology
       
   135 */
       
   136 	{
       
   137 public:
       
   138      DPipeChannel();
       
   139      virtual ~DPipeChannel();
       
   140 
       
   141     // inherited from DObject 
       
   142     virtual TInt RequestUserHandle (DThread* aThread, TOwnerType aType);
       
   143 
       
   144     // inherited from DLogicalChannelBase
       
   145     virtual TInt DoCreate (TInt aUnit, const TDesC8* anInfo, const TVersion& aVer);
       
   146 
       
   147 	virtual TInt Request(TInt aReqNo, TAny* a1, TAny* a2);
       
   148 	
       
   149 	
       
   150 private:
       
   151 
       
   152     // The user request is mapped 
       
   153     TInt DoControl(TInt aFunction, TAny* a1, TAny* a2);
       
   154     
       
   155     TInt DoRequest(TInt aReqNo, TRequestStatus* aStatus, TAny* a1,    
       
   156     TAny* a2);
       
   157 
       
   158     // This function will be called under DoControl()
       
   159     TInt PipeCreate(TAny* a1,  TAny* a2);
       
   160 	
       
   161     TInt PipeCreate(TInt aSize);
       
   162 	
       
   163     TInt PipeOpen(const TDesC* aName, RPipe::TChannelType aType);
       
   164     
       
   165     TInt PipeOpen (const TInt aId);
       
   166     
       
   167     TInt OpenOnReader(const TDesC* aName);
       
   168     
       
   169     TInt PipeDestroy(const TDesC* aName);
       
   170 
       
   171     TInt Read (TAny* aBuff, TInt aSize);
       
   172 
       
   173     TInt Write (TAny* aBuff, TInt aSize);
       
   174     
       
   175     TInt Size();
       
   176 
       
   177     TInt CloseHandle();
       
   178     
       
   179     TBool CheckCap();
       
   180     
       
   181     // Registration of the Asynchronous request
       
   182     TInt NotifySpaceAvailable (TInt aSize, TRequestStatus* aStat, TBool aAllowDisconnected);
       
   183 
       
   184     TInt NotifyDataAvailable (TRequestStatus* aStat, TBool aAllowDisconnected);
       
   185 
       
   186     TInt WaitNotification (TRequestStatus* aStat, TAny* aName , TInt aChoice);
       
   187 
       
   188    void Flush();
       
   189 	
       
   190 	TBool ValidCancellation(TInt aReqType);
       
   191 public:
       
   192 
       
   193 	void CancelRequest (TInt aReqType);
       
   194 	
       
   195 	void DoRequestCallback();
       
   196 	
       
   197 private:
       
   198 	/////// Accessed within pipe mutex ///////
       
   199 	
       
   200 	DThread *iRequestThread; ///< The thread awaiting notification.
       
   201 	TClientRequest* iClientRequest;
       
   202 
       
   203 	//Allows us to tell if a request cancellation is valid
       
   204 	TInt iRequestType; ///< Access within Pipe Mutex
       
   205 	
       
   206 	//////////////////////////////////////////
       
   207 
       
   208 
       
   209 	// Reference to  the DPipe
       
   210 	DPipe* iData;
       
   211 	
       
   212 	//Effectively constant
       
   213 	RPipe::TChannelType iChannelType;
       
   214 };
       
   215 
       
   216 
       
   217 
       
   218 class DPipe:public DBase
       
   219 /**
       
   220 This class represent the actual Kernel side Pipe. An instance of this class is constructed 
       
   221 when ever user creates a named/un-named pipe through the methods provided by user handler RPipe. 
       
   222 The owner of a DPipe instance is the DPipeDevice factory object and associates this DPipe 
       
   223 instance to the appropriate DPipeChannel instance. Each DPipe object is associated with two 
       
   224 DPipeChannel instances for read and writes operation
       
   225 
       
   226 @internalTechnology
       
   227 */
       
   228 {
       
   229 	friend class DPipeChannel;
       
   230 	friend class DPipeDevice;
       
   231 public:
       
   232 	
       
   233 	virtual ~DPipe();
       
   234 
       
   235 	// Creates a Named pipe
       
   236 	static DPipe* CreatePipe(const TDesC& aName, TInt aSize, TAny* aPolicy = NULL);
       
   237 
       
   238 	// check if the name referring  to a created pipe is valid.
       
   239 	TBool MatchName(const TDesC* aName);
       
   240 
       
   241 	// Check if the id referring to a created pipe is valid.
       
   242 	TBool MatchId(const TInt aId);
       
   243 
       
   244 
       
   245 	// Check if Buffer is Empty
       
   246 	TInt IsBufferEmpty();
       
   247 
       
   248 	// Write to Buffer
       
   249 	TInt Write(TAny* aBuf, TInt aSize);
       
   250 
       
   251 	// Read to Buffer
       
   252 	TInt Read(TAny* aBuf, TInt aSize);
       
   253 	
       
   254 	void SetReadEnd(DPipeChannel * aChannel);
       
   255 	
       
   256 	void SetWriteEnd(DPipeChannel * aChannel);
       
   257 
       
   258 
       
   259 	// Registering Notification from client thread
       
   260 	TInt RegisterSpaceAvailableNotification(TInt aSize);
       
   261 	
       
   262 	TInt RegisterDataAvailableNotification();
       
   263 	
       
   264 	TInt RegisterWaitNotification(TInt aChoice);	
       
   265 
       
   266 	//! Cancellation methods
       
   267 	void CancelSpaceAvailable();
       
   268 	
       
   269 	void CancelDataAvailable();
       
   270 	
       
   271 	void CancelWaitNotifier();
       
   272 	
       
   273 	TInt CloseReadEnd();
       
   274 	
       
   275 	TInt CloseWriteEnd();
       
   276 	
       
   277 	void CloseAll();
       
   278 
       
   279 	TBool IsNamedPipe();
       
   280 	
       
   281 	TBool IsPipeClosed();
       
   282 	
       
   283 	TBool IsReadEndOpened();
       
   284 	
       
   285 	TBool IsWriteEndOpened();
       
   286 	
       
   287 	TInt OpenId();
       
   288 	
       
   289 	TInt Size();
       
   290 	
       
   291 	void SetId(TInt aId);
       
   292 	
       
   293 	void FlushPipe();
       
   294 	
       
   295 	TInt AvailableDataCount();
       
   296 	
       
   297 	inline TSecurityPolicy* GetCap(){ return &iPolicy;}
       
   298 
       
   299 	
       
   300 private:
       
   301 	TInt ConstructPipe(const TDesC& aName, TInt aSize,TAny* aPolicy = NULL);
       
   302 	
       
   303 	inline void Wait()
       
   304 		{
       
   305 		Kern::MutexWait(*iPipeMutex);
       
   306 		DATAPAGING_TEST(Kern::SetRealtimeState(ERealtimeStateOn);)
       
   307 		}
       
   308 	
       
   309 	inline void Signal()
       
   310 		{
       
   311 		DATAPAGING_TEST(Kern::SetRealtimeState(ERealtimeStateOff);)
       
   312 		Kern::MutexSignal(*iPipeMutex);
       
   313 		}
       
   314 
       
   315 	void MaybeCompleteSpaceNotification();
       
   316 
       
   317 	inline DMutex& Mutex()
       
   318 		{
       
   319 		return *iPipeMutex;
       
   320 		}
       
   321 
       
   322 private:
       
   323 
       
   324 	//! constructor
       
   325 	DPipeChannel *iReadChannel;
       
   326 	
       
   327 	DPipeChannel *iWriteChannel;
       
   328 	
       
   329 	TKName iName;  //! TBuf<KMaxKernelName> TKName
       
   330 	
       
   331 	TInt iID;	
       
   332 
       
   333 	//! Members for Ring buffer
       
   334 	TInt iSize;
       
   335 	
       
   336 	TBool iFull;
       
   337 	
       
   338 	TUint8 *iBuffer;
       
   339 	
       
   340 	TInt iWritePointer;
       
   341 	
       
   342 	TInt iReadPointer;
       
   343 
       
   344 	//! Signify the presence of read and write channel
       
   345 	
       
   346 	TBool iSpaceAvailableRequest;
       
   347 	
       
   348 	TBool iDataAvailableRequest;
       
   349 	
       
   350 	TBool iWaitRequest;
       
   351 	
       
   352 	TInt  iSpaceAvailableSize;
       
   353 	
       
   354 	DMutex *iPipeMutex;
       
   355 	DMutex *iReadMutex;
       
   356 	DMutex *iWriteMutex;
       
   357 
       
   358 	
       
   359 	TSecurityPolicy iPolicy;
       
   360 	
       
   361 };
       
   362 
       
   363 /**
       
   364 Acquire the given lock on construction and release
       
   365 on destruction.
       
   366 @internalTechnology
       
   367 */
       
   368 template<typename T>
       
   369 class TAutoWait
       
   370 	{
       
   371 public:
       
   372 	inline TAutoWait(T& aLock)
       
   373 		:iLock(aLock)
       
   374 		{
       
   375 		Wait();
       
   376 		}
       
   377 
       
   378 	inline ~TAutoWait()
       
   379 		{
       
   380 		Signal();
       
   381 		}
       
   382 
       
   383 
       
   384 private:
       
   385 	TAutoWait(TAutoWait&);
       
   386 	TAutoWait& operator= (TAutoWait&);
       
   387 
       
   388 	//disallow allocating on the heap since
       
   389 	//this won't do what we want
       
   390 	void* operator new(TUint aSize);
       
   391 
       
   392 	inline void Wait();
       
   393 	inline void Signal();
       
   394 
       
   395 	T& iLock;
       
   396 	};
       
   397 
       
   398 template<>
       
   399 void TAutoWait<DMutex>::Wait()
       
   400 	{
       
   401 	NKern::ThreadEnterCS();
       
   402 	Kern::MutexWait(iLock);
       
   403 	}
       
   404 
       
   405 template<>
       
   406 void TAutoWait<DMutex>::Signal()
       
   407 	{
       
   408 	Kern::MutexSignal(iLock);
       
   409 	NKern::ThreadLeaveCS();
       
   410 	}
       
   411 
       
   412 #endif
       
   413 
       
   414 
       
   415 
       
   416