1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/os/kernelhwsrv/kernel/eka/include/drivers/dpipe.h Fri Jun 15 03:10:57 2012 +0200
1.3 @@ -0,0 +1,416 @@
1.4 +// Copyright (c) 2006-2009 Nokia Corporation and/or its subsidiary(-ies).
1.5 +// All rights reserved.
1.6 +// This component and the accompanying materials are made available
1.7 +// under the terms of the License "Eclipse Public License v1.0"
1.8 +// which accompanies this distribution, and is available
1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
1.10 +//
1.11 +// Initial Contributors:
1.12 +// Nokia Corporation - initial contribution.
1.13 +//
1.14 +// Contributors:
1.15 +//
1.16 +// Description:
1.17 +//
1.18 +
1.19 +
1.20 +
1.21 +
1.22 +#ifndef __DPIPE_H__
1.23 +#define __DPIPE_H__
1.24 +
1.25 +#define _TEST__
1.26 +
1.27 +#if !defined(__KERNEL_H__)
1.28 +#include <kernel/kernel.h>
1.29 +#endif
1.30 +
1.31 +#include <rpipe.h>
1.32 +
1.33 +const TInt KIdBase = 0x0;
1.34 +
1.35 +class DPipe;
1.36 +
1.37 +class DPipeDevice : public DLogicalDevice
1.38 +/**
1.39 +The factory class is derived from Dlogical device. The user side calls
1.40 +User::LoadLogicalDevice() to load the LDD dll and create the LDD
1.41 +factory object in the kernel heap.
1.42 +@internalTechnology
1.43 +*/
1.44 +{
1.45 +public:
1.46 + /**
1.47 + Set the version number
1.48 + */
1.49 + DPipeDevice();
1.50 +
1.51 + ~DPipeDevice();
1.52 +
1.53 + // Inherited from DLogicalDevice
1.54 + /**
1.55 + Second stage constructor and at least set a name for the
1.56 + driver object.
1.57 + */
1.58 + virtual TInt Install();
1.59 +
1.60 +
1.61 + virtual void GetCaps(TDes8& aDes) const;
1.62 +
1.63 + /**
1.64 + Called by the Kernel's Device driver framework to create a logical
1.65 + Channel. This called in the context of the user thread. which requested
1.66 + the creation of the logical channel.It checks if maximum pipe creation
1.67 + has reached before creating a new Kernel pipe object.
1.68 + @param aChannel Set to point to the created logical channel
1.69 +
1.70 + @return KErrNone if successful, otherwise system wide error codes.
1.71 + */
1.72 + virtual TInt Create(DLogicalChannelBase*& aChannel);
1.73 +
1.74 +
1.75 + /**
1.76 + Called by the Logical channel instance to create DPipe and
1.77 + associate itself.
1.78 + */
1.79 + TInt CreatePipe(const TDesC& aName, TInt aSize, DPipe*& aPipe, TAny* aCapCheck = NULL);
1.80 +
1.81 + DPipe* CreatePipe(TInt aSize);
1.82 +
1.83 + DPipe* FindNamedPipe(const TDesC* aName);
1.84 +
1.85 + DPipe* FindUnnamedPipe(const TInt aId);
1.86 +
1.87 + TInt Destroy(const TDesC* aName);
1.88 +
1.89 + TInt Close(TInt aId);
1.90 +
1.91 +
1.92 + inline DMutex& Mutex()
1.93 + {
1.94 + return *iMutex;
1.95 + }
1.96 +
1.97 + inline void Wait()
1.98 + {
1.99 + Kern::MutexWait(*iMutex);
1.100 + }
1.101 +
1.102 + inline void Signal()
1.103 + {
1.104 + Kern::MutexSignal(*iMutex);
1.105 + }
1.106 +
1.107 + private:
1.108 + TInt GenerateId();
1.109 +
1.110 + TInt AddPipe(DPipe* aObj);
1.111 +
1.112 + void RemovePipe(DPipe** aObj);
1.113 +
1.114 +
1.115 +private:
1.116 + //! Represents the Data in a pipe.
1.117 + DPipe **iDpipes;
1.118 +
1.119 + DMutex *iMutex;
1.120 +
1.121 + TInt iAllocated;
1.122 +
1.123 + TInt iCount;
1.124 +
1.125 + TInt iIdindex;
1.126 +
1.127 +};
1.128 +
1.129 +
1.130 +
1.131 +class DPipeChannel : public DLogicalChannelBase
1.132 +/**
1.133 +DPipe Channel provides the Kernel interface to the DPipe. The request from the RPipe handler
1.134 +in the context of user thread, is transfered to DPipeChannel class. This is the interface
1.135 +between the DPipe kernel object and the user request through RPipe handler.
1.136 +
1.137 +@internalTechnology
1.138 +*/
1.139 + {
1.140 +public:
1.141 + DPipeChannel();
1.142 + virtual ~DPipeChannel();
1.143 +
1.144 + // inherited from DObject
1.145 + virtual TInt RequestUserHandle (DThread* aThread, TOwnerType aType);
1.146 +
1.147 + // inherited from DLogicalChannelBase
1.148 + virtual TInt DoCreate (TInt aUnit, const TDesC8* anInfo, const TVersion& aVer);
1.149 +
1.150 + virtual TInt Request(TInt aReqNo, TAny* a1, TAny* a2);
1.151 +
1.152 +
1.153 +private:
1.154 +
1.155 + // The user request is mapped
1.156 + TInt DoControl(TInt aFunction, TAny* a1, TAny* a2);
1.157 +
1.158 + TInt DoRequest(TInt aReqNo, TRequestStatus* aStatus, TAny* a1,
1.159 + TAny* a2);
1.160 +
1.161 + // This function will be called under DoControl()
1.162 + TInt PipeCreate(TAny* a1, TAny* a2);
1.163 +
1.164 + TInt PipeCreate(TInt aSize);
1.165 +
1.166 + TInt PipeOpen(const TDesC* aName, RPipe::TChannelType aType);
1.167 +
1.168 + TInt PipeOpen (const TInt aId);
1.169 +
1.170 + TInt OpenOnReader(const TDesC* aName);
1.171 +
1.172 + TInt PipeDestroy(const TDesC* aName);
1.173 +
1.174 + TInt Read (TAny* aBuff, TInt aSize);
1.175 +
1.176 + TInt Write (TAny* aBuff, TInt aSize);
1.177 +
1.178 + TInt Size();
1.179 +
1.180 + TInt CloseHandle();
1.181 +
1.182 + TBool CheckCap();
1.183 +
1.184 + // Registration of the Asynchronous request
1.185 + TInt NotifySpaceAvailable (TInt aSize, TRequestStatus* aStat, TBool aAllowDisconnected);
1.186 +
1.187 + TInt NotifyDataAvailable (TRequestStatus* aStat, TBool aAllowDisconnected);
1.188 +
1.189 + TInt WaitNotification (TRequestStatus* aStat, TAny* aName , TInt aChoice);
1.190 +
1.191 + void Flush();
1.192 +
1.193 + TBool ValidCancellation(TInt aReqType);
1.194 +public:
1.195 +
1.196 + void CancelRequest (TInt aReqType);
1.197 +
1.198 + void DoRequestCallback();
1.199 +
1.200 +private:
1.201 + /////// Accessed within pipe mutex ///////
1.202 +
1.203 + DThread *iRequestThread; ///< The thread awaiting notification.
1.204 + TClientRequest* iClientRequest;
1.205 +
1.206 + //Allows us to tell if a request cancellation is valid
1.207 + TInt iRequestType; ///< Access within Pipe Mutex
1.208 +
1.209 + //////////////////////////////////////////
1.210 +
1.211 +
1.212 + // Reference to the DPipe
1.213 + DPipe* iData;
1.214 +
1.215 + //Effectively constant
1.216 + RPipe::TChannelType iChannelType;
1.217 +};
1.218 +
1.219 +
1.220 +
1.221 +class DPipe:public DBase
1.222 +/**
1.223 +This class represent the actual Kernel side Pipe. An instance of this class is constructed
1.224 +when ever user creates a named/un-named pipe through the methods provided by user handler RPipe.
1.225 +The owner of a DPipe instance is the DPipeDevice factory object and associates this DPipe
1.226 +instance to the appropriate DPipeChannel instance. Each DPipe object is associated with two
1.227 +DPipeChannel instances for read and writes operation
1.228 +
1.229 +@internalTechnology
1.230 +*/
1.231 +{
1.232 + friend class DPipeChannel;
1.233 + friend class DPipeDevice;
1.234 +public:
1.235 +
1.236 + virtual ~DPipe();
1.237 +
1.238 + // Creates a Named pipe
1.239 + static DPipe* CreatePipe(const TDesC& aName, TInt aSize, TAny* aPolicy = NULL);
1.240 +
1.241 + // check if the name referring to a created pipe is valid.
1.242 + TBool MatchName(const TDesC* aName);
1.243 +
1.244 + // Check if the id referring to a created pipe is valid.
1.245 + TBool MatchId(const TInt aId);
1.246 +
1.247 +
1.248 + // Check if Buffer is Empty
1.249 + TInt IsBufferEmpty();
1.250 +
1.251 + // Write to Buffer
1.252 + TInt Write(TAny* aBuf, TInt aSize);
1.253 +
1.254 + // Read to Buffer
1.255 + TInt Read(TAny* aBuf, TInt aSize);
1.256 +
1.257 + void SetReadEnd(DPipeChannel * aChannel);
1.258 +
1.259 + void SetWriteEnd(DPipeChannel * aChannel);
1.260 +
1.261 +
1.262 + // Registering Notification from client thread
1.263 + TInt RegisterSpaceAvailableNotification(TInt aSize);
1.264 +
1.265 + TInt RegisterDataAvailableNotification();
1.266 +
1.267 + TInt RegisterWaitNotification(TInt aChoice);
1.268 +
1.269 + //! Cancellation methods
1.270 + void CancelSpaceAvailable();
1.271 +
1.272 + void CancelDataAvailable();
1.273 +
1.274 + void CancelWaitNotifier();
1.275 +
1.276 + TInt CloseReadEnd();
1.277 +
1.278 + TInt CloseWriteEnd();
1.279 +
1.280 + void CloseAll();
1.281 +
1.282 + TBool IsNamedPipe();
1.283 +
1.284 + TBool IsPipeClosed();
1.285 +
1.286 + TBool IsReadEndOpened();
1.287 +
1.288 + TBool IsWriteEndOpened();
1.289 +
1.290 + TInt OpenId();
1.291 +
1.292 + TInt Size();
1.293 +
1.294 + void SetId(TInt aId);
1.295 +
1.296 + void FlushPipe();
1.297 +
1.298 + TInt AvailableDataCount();
1.299 +
1.300 + inline TSecurityPolicy* GetCap(){ return &iPolicy;}
1.301 +
1.302 +
1.303 +private:
1.304 + TInt ConstructPipe(const TDesC& aName, TInt aSize,TAny* aPolicy = NULL);
1.305 +
1.306 + inline void Wait()
1.307 + {
1.308 + Kern::MutexWait(*iPipeMutex);
1.309 + DATAPAGING_TEST(Kern::SetRealtimeState(ERealtimeStateOn);)
1.310 + }
1.311 +
1.312 + inline void Signal()
1.313 + {
1.314 + DATAPAGING_TEST(Kern::SetRealtimeState(ERealtimeStateOff);)
1.315 + Kern::MutexSignal(*iPipeMutex);
1.316 + }
1.317 +
1.318 + void MaybeCompleteSpaceNotification();
1.319 +
1.320 + inline DMutex& Mutex()
1.321 + {
1.322 + return *iPipeMutex;
1.323 + }
1.324 +
1.325 +private:
1.326 +
1.327 + //! constructor
1.328 + DPipeChannel *iReadChannel;
1.329 +
1.330 + DPipeChannel *iWriteChannel;
1.331 +
1.332 + TKName iName; //! TBuf<KMaxKernelName> TKName
1.333 +
1.334 + TInt iID;
1.335 +
1.336 + //! Members for Ring buffer
1.337 + TInt iSize;
1.338 +
1.339 + TBool iFull;
1.340 +
1.341 + TUint8 *iBuffer;
1.342 +
1.343 + TInt iWritePointer;
1.344 +
1.345 + TInt iReadPointer;
1.346 +
1.347 + //! Signify the presence of read and write channel
1.348 +
1.349 + TBool iSpaceAvailableRequest;
1.350 +
1.351 + TBool iDataAvailableRequest;
1.352 +
1.353 + TBool iWaitRequest;
1.354 +
1.355 + TInt iSpaceAvailableSize;
1.356 +
1.357 + DMutex *iPipeMutex;
1.358 + DMutex *iReadMutex;
1.359 + DMutex *iWriteMutex;
1.360 +
1.361 +
1.362 + TSecurityPolicy iPolicy;
1.363 +
1.364 +};
1.365 +
1.366 +/**
1.367 +Acquire the given lock on construction and release
1.368 +on destruction.
1.369 +@internalTechnology
1.370 +*/
1.371 +template<typename T>
1.372 +class TAutoWait
1.373 + {
1.374 +public:
1.375 + inline TAutoWait(T& aLock)
1.376 + :iLock(aLock)
1.377 + {
1.378 + Wait();
1.379 + }
1.380 +
1.381 + inline ~TAutoWait()
1.382 + {
1.383 + Signal();
1.384 + }
1.385 +
1.386 +
1.387 +private:
1.388 + TAutoWait(TAutoWait&);
1.389 + TAutoWait& operator= (TAutoWait&);
1.390 +
1.391 + //disallow allocating on the heap since
1.392 + //this won't do what we want
1.393 + void* operator new(TUint aSize);
1.394 +
1.395 + inline void Wait();
1.396 + inline void Signal();
1.397 +
1.398 + T& iLock;
1.399 + };
1.400 +
1.401 +template<>
1.402 +void TAutoWait<DMutex>::Wait()
1.403 + {
1.404 + NKern::ThreadEnterCS();
1.405 + Kern::MutexWait(iLock);
1.406 + }
1.407 +
1.408 +template<>
1.409 +void TAutoWait<DMutex>::Signal()
1.410 + {
1.411 + Kern::MutexSignal(iLock);
1.412 + NKern::ThreadLeaveCS();
1.413 + }
1.414 +
1.415 +#endif
1.416 +
1.417 +
1.418 +
1.419 +