diff -r 000000000000 -r a41df078684a kernel/eka/euser/us_mqueue.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/kernel/eka/euser/us_mqueue.cpp Mon Oct 19 15:55:17 2009 +0100 @@ -0,0 +1,388 @@ +// Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the License "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// e32\euser\us_mqueue.cpp +// +// + +#include "us_std.h" +#include +#include + + + + +EXPORT_C TInt RMsgQueueBase::CreateLocal(TInt aSize, TInt aMsgLength, TOwnerType aType) +/** +Creates a message queue that is private to the current process, +and opens a handle to that message queue. + +The Kernel side object representing the message queue is +unnamed. This means that it is not possible to search for the message queue, +and this makes it local to the current process. + +By default, any thread in the process can use this handle to +access the message queue. However, specifying EOwnerThread as the +third parameter to this function means that only the creating thread can use +the handle to access the message queue; any other thread in this process that +wants to access the message queue must duplicate this handle. + +@param aSize The number of message 'slots' in the queue. + This must be a positive value, i.e. greater than zero. +@param aMsgLength The size of each message for the queue, this cannot exceed + KMaxLength. +@param aType The type of handle to be created. + EOwnerProcess is the default value, if not explicitly specified. + +@return KErrNone if the queue is created sucessfully, otherwise one of + the other system wide error codes. + +@panic KERN-EXEC 49 if aSize is less than or equal to zero. +@panic KERN-EXEC 48 if aMsgLength is not a multiple of 4 bytes, + is less than 4, or is greater than KMaxLength. + +@see KMaxLength +*/ + { + return SetReturnedHandle(Exec::MsgQueueCreate(NULL, aSize, aMsgLength, aType)); + } + + + + +EXPORT_C TInt RMsgQueueBase::CreateGlobal(const TDesC &aName,TInt aSize, TInt aMsgLength,TOwnerType aType) +/** +Creates a global message queue, and opens a handle to that +message queue. + +The kernel side object representing the message queue is given +the name contained in the specified descriptor, which makes it global, +i.e. it is visible to all processes. This means that any thread in any +process can search for the message queue, and open a handle to it. +If the specified name is empty the kernel side object representing the +message queue is unnamed and so cannot be opened by name or searched +for. It can however be passed to another process as a process parameter +or via IPC. + +By default, any thread in the process can use this handle to +access the message queue. However, specifying EOwnerThread as the +fourth parameter to this function, means that only the creating thread can use +this handle to access the message queue; any other thread in this process that +wants to access the message queue must either duplicate this handle or use +OpenGlobal(). + +@param aName The name to be assigned to the message queue +@param aSize The number of message 'slots' in the queue. + This must be a positive value, i.e. greater than zero. +@param aMsgLength The size of each message for the queue, this cannot exceed + KMaxLength. +@param aType The type of handle to be created. + EOwnerProcess is the default value, if not explicitly specified. + +@return KErrNone if the queue is created sucessfully, otherwise one of + the other system wide error codes. + +@panic KERN-EXEC 49 if aSize is less than or equal to zero. +@panic KERN-EXEC 48 if aMsgLength is not a multiple of 4 bytes, + is less than 4, or is greater than KMaxLength. + +@see KMaxLength +@see RMsgQueueBase::OpenGlobal +*/ + { + TInt r = User::ValidateName(aName); + if(KErrNone!=r) + return r; + TBuf8 name8; + name8.Copy(aName); + return SetReturnedHandle(Exec::MsgQueueCreate(&name8, aSize, aMsgLength, aType)); + } + + + + +EXPORT_C TInt RMsgQueueBase::OpenGlobal(const TDesC &aName, TOwnerType aType) +/** +Opens a global message queue. + +Global message queues are identified by name. + +By default, any thread in the process can use this handle to +access the message queue. However, specifying EOwnerThread as the +second parameter to this function, means that only the opening thread can use +this handle to access the message queue; any other thread in this process that +wants to access the message queue must either duplicate this handle or use +OpenGlobal() again. + +@param aName The name of the message queue. +@param aType The type of handle to be created. + EOwnerProcess is the default value, if not explicitly specified. + +@return KErrNone if queue opened sucessfully, otherwise one of + the other system wide error codes. + +@see RMsgQueueBase::OpenGlobal +*/ + { + return OpenByName(aName,aType,EMsgQueue); + } + + + +//realtime +EXPORT_C TInt RMsgQueueBase::Send(const TAny* aPtr, TInt aLength) +/** + +Sends a message through this queue. + +The function does not wait (i.e. block), if the queue is full. + +Note that, once on the queue, the content of the message cannot +be accessed other than through a call to Receive() or ReceiveBlocking(). + +@param aPtr A pointer to the message data +@param aLength The length of the message data, this must not exceed + the queue's message size. + +@return KErrNone, if successful; + KErrOverflow, if queue is full, + +@panic KERN-EXEC 48 if aLength is greater than the message length specified + when the queue was created, or if aLength is less than or equal to zero. + +@see RMsgQueueBase::Receive +@see RMsgQueueBase::ReceiveBlocking +*/ + { + return Exec::MsgQueueSend(iHandle, aPtr, aLength); + } + + + + +EXPORT_C void RMsgQueueBase::SendBlocking(const TAny* aPtr, TInt aLength) +/** +Sends a message through this queue, and waits for space to become available +if the queue is full. + +The function uses NotifySpaceAvailable() to provide the blocking operation. +Note that it is not possible to cancel a call to SendBlocking(). + +@param aPtr A pointer to the message data. +@param aLength The length of the message data, this must not exceed + the queue's message size. + +@panic KERN-EXEC 48 if aLength is greater than the message length specified + when the queue was created, or if aLength is less than or equal to zero. + +@see RMsgQueueBase::NotifySpaceAvailable +*/ + { + TRequestStatus stat; + while (Exec::MsgQueueSend(iHandle, aPtr, aLength) == KErrOverflow) + { + stat = KRequestPending; + Exec::MsgQueueNotifySpaceAvailable(iHandle, stat); + User::WaitForRequest(stat); + } + } + + + +//realtime +EXPORT_C TInt RMsgQueueBase::Receive(TAny* aPtr, TInt aLength) +/** + +Retrieves the first message in the queue. + +The function does not wait (i.e. block), if the queue is empty. + +@param aPtr A pointer to a buffer to receive the message data. +@param aLength The length of the buffer for the message, this must match + the queue's message size. + +@return KErrNone, ifsuccessful; + KErrUnderflow, if the queue is empty. + +@panic KERN-EXEC 48 if aLength is not equal to the message length + specified when the queue was created. +*/ + { + return Exec::MsgQueueReceive(iHandle, aPtr, aLength); + } + + + + +EXPORT_C void RMsgQueueBase::ReceiveBlocking(TAny* aPtr, TInt aLength) +/** +Retrieves the first message in the queue, and waits if the queue is empty. + +The function uses NotifyDataAvailable() to provide the blocking operation. +Note it is not possible to cancel a call to ReceiveBlocking(). + +@param aPtr A pointer to a buffer to receive the message data. +@param aLength The length of the buffer for the message, this must match + the queue's message size. + +@panic KERN-EXEC 48 if aLength is not equal to the message length + specified when the queue was created. + +@see RMsgQueueBase::NotifyDataAvailable +*/ + { + TRequestStatus stat; + while (Exec::MsgQueueReceive(iHandle, aPtr, aLength) == KErrUnderflow) + { + stat = KRequestPending; + Exec::MsgQueueNotifyDataAvailable(iHandle, stat); + User::WaitForRequest(stat); + } + } + + + + +EXPORT_C void RMsgQueueBase::NotifySpaceAvailable(TRequestStatus& aStatus) +/** +Requests notification when space becomes available in the queue. + +This is an asynchronous request that completes when there is at least +one 'slot'available in the queue. + +A thread can have only one space available notification request outstanding on +this message queue. If a second request is made before +the first request completes, then the calling thread is panicked. + +@param aStatus The request status object to be completed when space + becomes available. + +@panic KERN-EXEC 47 if a second request is made + while the first request remains outstanding. +*/ + { + aStatus = KRequestPending; + Exec::MsgQueueNotifySpaceAvailable(iHandle, aStatus); + } + + + + +EXPORT_C void RMsgQueueBase::CancelSpaceAvailable() +/** +Cancels an outstanding space available notification request. + +If the request is not already complete, then it now completes with KErrCancel. + +@panic KERN-EXEC 50 if attempting to cancel an outstanding request made by + a thread in a different process. + +@see RMsgQueueBase::NotifySpaceAvailable +*/ + { + Exec::MsgQueueCancelSpaceAvailable(iHandle); + } + + + + +EXPORT_C void RMsgQueueBase::NotifyDataAvailable(TRequestStatus& aStatus) +/** +Requests notification when there is at least one message in the queue. + +A thread can have only one data available notification request outstanding on +this message queue. If a second request is made before +the first request completes, then the calling thread is panicked. + +@param aStatus The request status object to be completed when + a message becomes available. + +@panic KERN-EXEC 47 if a second request is made + while the first request remains outstanding. +*/ + { + aStatus = KRequestPending; + Exec::MsgQueueNotifyDataAvailable(iHandle, aStatus); + } + + + + +EXPORT_C void RMsgQueueBase::CancelDataAvailable() +/** +Cancels an outstanding data available notification request. + +If the request is not already complete, then it now completes with KErrCancel. + +@panic KERN-EXEC 50 if attempting to cancel an outstanding request made by + a thread in a different process. + +@see RMsgQueueBase::NotifyDataAvailable +*/ + { + Exec::MsgQueueCancelDataAvailable(iHandle); + } + + + + +EXPORT_C TInt RMsgQueueBase::MessageSize() +/** +Gets the size of message slots in the queue. + +@return The size of a message slot in the queue. +*/ + { + return Exec::MsgQueueSize(iHandle); + } + + + + +EXPORT_C TInt RMsgQueueBase::Open(RMessagePtr2 aMessage, TInt aParam, TOwnerType aType) +/** +Opens a global message queue using a handle passed in a server message. + +By default, any thread in the process can use this handle to +access the message queue. However, specifying EOwnerThread as the +third parameter to this function, means that only the opening thread can use +this handle to access the message queue. + +@param aMessage The server message. +@param aParam The number of the message parameter which holds the handle. +@param aType The type of handle to be created. + EOwnerProcess is the default value, if not explicitly specified. +*/ + { + return SetReturnedHandle(Exec::MessageOpenObject(aMessage.Handle(),EMsgQueue,aParam,aType)); + } + + + + +EXPORT_C TInt RMsgQueueBase::Open(TInt aArgumentIndex, TOwnerType aType) +/** +Opens a message queue using the handle passed in during process creation. + +@param aArgumentIndex The number on the parameter which holds the handle. +@param aType The type of handle to be created. + EOwnerProcess is the default value, if not explicitly + specified. + +@return KErrNone, ifsuccessful; + KErrArgument, if aArgumentIndex doesn't contain a message queue handle; + KErrNotFound, if aArgumentIndex is empty. +*/ + { + return SetReturnedHandle(Exec::ProcessGetHandleParameter(aArgumentIndex, EMsgQueue, aType)); + }