os/kernelhwsrv/kernel/eka/euser/us_mqueue.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 // Copyright (c) 2002-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 // e32\euser\us_mqueue.cpp
    15 // 
    16 //
    17 
    18 #include "us_std.h"
    19 #include <e32kpan.h>
    20 #include <e32msgqueue.h>
    21 
    22 
    23 
    24 
    25 EXPORT_C TInt RMsgQueueBase::CreateLocal(TInt aSize, TInt aMsgLength, TOwnerType aType)
    26 /**
    27 Creates a message queue that is private to the current process,
    28 and opens a handle to that message queue.
    29 
    30 The Kernel side object representing the message queue is
    31 unnamed. This means that it is not possible to search for the message queue,
    32 and this makes it local to the current process.
    33 
    34 By default, any thread in the process can use this handle to
    35 access the message queue. However, specifying EOwnerThread as the
    36 third parameter to this function means that only the creating thread can use
    37 the handle to access the message queue; any other thread in this process that
    38 wants to access the message queue must duplicate this handle.
    39 		
    40 @param aSize      The number of message 'slots' in the queue.
    41                   This must be a positive value, i.e. greater than zero.
    42 @param aMsgLength The size of each message for the queue, this cannot exceed
    43                   KMaxLength.
    44 @param aType      The type of handle to be created.
    45                   EOwnerProcess is the default value, if not explicitly specified.
    46 
    47 @return KErrNone if the queue is created sucessfully, otherwise one of
    48         the other system wide error codes.
    49 		
    50 @panic KERN-EXEC 49 if aSize is less than or equal to zero.
    51 @panic KERN-EXEC 48 if aMsgLength is not a multiple of 4 bytes, 
    52                     is less than 4, or is greater than KMaxLength. 
    53                     
    54 @see KMaxLength                    
    55 */
    56 	{
    57 	return SetReturnedHandle(Exec::MsgQueueCreate(NULL, aSize, aMsgLength, aType));
    58 	}
    59 
    60 
    61 
    62 
    63 EXPORT_C TInt RMsgQueueBase::CreateGlobal(const TDesC &aName,TInt aSize, TInt aMsgLength,TOwnerType aType)
    64 /**
    65 Creates a global message queue, and opens a handle to that
    66 message queue.
    67 
    68 The kernel side object representing the message queue is given
    69 the name contained in the specified descriptor, which makes it global,
    70 i.e. it is visible to all processes. This means that any thread in any
    71 process can search for the message queue, and open a handle to it.
    72 If the specified name is empty the kernel side object representing the
    73 message queue is unnamed and so cannot be opened by name or searched
    74 for. It can however be passed to another process as a process parameter
    75 or via IPC.
    76 
    77 By default, any thread in the process can use this handle to
    78 access the message queue. However, specifying EOwnerThread as the
    79 fourth parameter to this function, means that only the creating thread can use
    80 this handle to access the message queue; any other thread in this process that
    81 wants to access the message queue must either duplicate this handle or use 
    82 OpenGlobal().
    83 
    84 @param aName      The name to be assigned to the message queue
    85 @param aSize      The number of message 'slots' in the queue.
    86                   This must be a positive value, i.e. greater than zero.
    87 @param aMsgLength The size of each message for the queue, this cannot exceed
    88                   KMaxLength.
    89 @param aType      The type of handle to be created.
    90                   EOwnerProcess is the default value, if not explicitly specified.
    91 
    92 @return KErrNone if the queue is created sucessfully, otherwise one of
    93         the other system wide error codes.
    94 		
    95 @panic KERN-EXEC 49 if aSize is less than or equal to zero.
    96 @panic KERN-EXEC 48 if aMsgLength is not a multiple of 4 bytes, 
    97                     is less than 4, or is greater than KMaxLength. 
    98                     
    99 @see KMaxLength                    
   100 @see RMsgQueueBase::OpenGlobal
   101 */
   102 	{
   103 	TInt r = User::ValidateName(aName);
   104 	if(KErrNone!=r)
   105 		return r;
   106 	TBuf8<KMaxKernelName> name8;
   107 	name8.Copy(aName);
   108 	return SetReturnedHandle(Exec::MsgQueueCreate(&name8, aSize, aMsgLength, aType));
   109 	}
   110 
   111 
   112 
   113 
   114 EXPORT_C TInt RMsgQueueBase::OpenGlobal(const TDesC &aName, TOwnerType aType)
   115 /**
   116 Opens a global message queue.
   117 
   118 Global message queues are identified by name.
   119 
   120 By default, any thread in the process can use this handle to
   121 access the message queue. However, specifying EOwnerThread as the
   122 second parameter to this function, means that only the opening thread can use
   123 this handle to access the message queue; any other thread in this process that
   124 wants to access the message queue must either duplicate this handle or use
   125 OpenGlobal() again.
   126 
   127 @param aName The name of the message queue.
   128 @param aType The type of handle to be created.
   129              EOwnerProcess is the default value, if not explicitly specified.
   130 
   131 @return KErrNone if queue opened sucessfully, otherwise one of
   132         the other system wide error codes.
   133 
   134 @see RMsgQueueBase::OpenGlobal
   135 */
   136 	{
   137 	return OpenByName(aName,aType,EMsgQueue);
   138 	}
   139 
   140 
   141 
   142 //realtime
   143 EXPORT_C TInt RMsgQueueBase::Send(const TAny* aPtr, TInt aLength)
   144 /**
   145 
   146 Sends a message through this queue.
   147 
   148 The function does not wait (i.e. block), if the queue is full.
   149 
   150 Note that, once on the queue, the content of the message cannot
   151 be accessed other than through a call to Receive() or ReceiveBlocking().
   152 		 
   153 @param aPtr    A pointer to the message data
   154 @param aLength The length of the message data, this must not exceed
   155                the queue's message size.
   156 				
   157 @return  KErrNone, if successful;
   158          KErrOverflow, if queue is full,
   159 
   160 @panic KERN-EXEC 48 if aLength is greater than the message length specified
   161        when the queue was created, or if aLength is less than or equal to zero.
   162 
   163 @see RMsgQueueBase::Receive
   164 @see RMsgQueueBase::ReceiveBlocking
   165 */
   166 	{
   167 	return Exec::MsgQueueSend(iHandle, aPtr, aLength);
   168 	}
   169 
   170 
   171 
   172 
   173 EXPORT_C void RMsgQueueBase::SendBlocking(const TAny* aPtr, TInt aLength)
   174 /**
   175 Sends a message through this queue, and waits for space to become available 
   176 if the queue is full.
   177 
   178 The function uses NotifySpaceAvailable() to provide the blocking operation. 
   179 Note that it is not possible to cancel a call to SendBlocking().
   180 
   181 @param aPtr    A pointer to the message data.
   182 @param aLength The length of the message data, this must not exceed
   183                the queue's message size.
   184 
   185 @panic KERN-EXEC 48 if aLength is greater than the message length specified
   186        when the queue was created, or if aLength is less than or equal to zero.
   187        
   188 @see RMsgQueueBase::NotifySpaceAvailable
   189 */
   190 	{
   191 	TRequestStatus stat;
   192 	while (Exec::MsgQueueSend(iHandle, aPtr, aLength) == KErrOverflow)
   193 		{
   194 		stat = KRequestPending;
   195 		Exec::MsgQueueNotifySpaceAvailable(iHandle, stat);
   196 		User::WaitForRequest(stat);
   197 		}
   198 	}
   199 
   200 
   201 
   202 //realtime
   203 EXPORT_C TInt RMsgQueueBase::Receive(TAny* aPtr, TInt aLength)
   204 /**
   205 
   206 Retrieves the first message in the queue.
   207 
   208 The function does not wait (i.e. block), if the queue is empty.
   209 
   210 @param aPtr    A pointer to a buffer to receive the message data.
   211 @param aLength The length of the buffer for the message, this must match
   212                the queue's message size.
   213 
   214 @return KErrNone, ifsuccessful;
   215         KErrUnderflow, if the queue is empty.
   216         
   217 @panic KERN-EXEC 48 if aLength is not equal to the message length
   218        specified when the queue was created.
   219 */
   220 	{
   221 	return Exec::MsgQueueReceive(iHandle, aPtr, aLength);
   222 	}
   223 
   224 
   225 
   226 
   227 EXPORT_C void RMsgQueueBase::ReceiveBlocking(TAny* aPtr, TInt aLength)
   228 /**
   229 Retrieves the first message in the queue, and waits if the queue is empty.
   230 			 
   231 The function uses NotifyDataAvailable() to provide the blocking operation.
   232 Note it is not possible to cancel a call to ReceiveBlocking().
   233 
   234 @param aPtr    A pointer to a buffer to receive the message data.
   235 @param aLength The length of the buffer for the message, this must match
   236                the queue's message size.
   237                
   238 @panic KERN-EXEC 48 if aLength is not equal to the message length
   239        specified when the queue was created.
   240        
   241 @see RMsgQueueBase::NotifyDataAvailable
   242 */
   243 	{
   244 	TRequestStatus stat;
   245 	while (Exec::MsgQueueReceive(iHandle, aPtr, aLength) == KErrUnderflow)
   246 		{
   247 		stat = KRequestPending;
   248 		Exec::MsgQueueNotifyDataAvailable(iHandle, stat);
   249 		User::WaitForRequest(stat);
   250 		}
   251 	}
   252 
   253 
   254 
   255 
   256 EXPORT_C void RMsgQueueBase::NotifySpaceAvailable(TRequestStatus& aStatus)
   257 /**
   258 Requests notification when space becomes available in the queue.
   259 	
   260 This is an asynchronous request that completes when there is at least
   261 one 'slot'available in the queue.
   262 
   263 A thread can have only one space available notification request	outstanding on
   264 this message queue. If a second request is made before
   265 the first request completes, then the calling thread is panicked.
   266 
   267 @param aStatus The request status object to be completed when space
   268                becomes available.
   269 
   270 @panic KERN-EXEC 47 if a second request is made
   271        while the first request remains outstanding.
   272 */
   273 	{
   274 	aStatus = KRequestPending;
   275 	Exec::MsgQueueNotifySpaceAvailable(iHandle, aStatus);
   276 	}
   277 
   278 
   279 
   280 
   281 EXPORT_C void RMsgQueueBase::CancelSpaceAvailable()
   282 /**
   283 Cancels an outstanding space available notification	request.
   284 	
   285 If the request is not already complete, then it now completes with KErrCancel.
   286 	
   287 @panic KERN-EXEC 50 if attempting to cancel an outstanding request made by
   288        a thread in a different process.
   289 			
   290 @see RMsgQueueBase::NotifySpaceAvailable
   291 */
   292 	{
   293 	Exec::MsgQueueCancelSpaceAvailable(iHandle);
   294 	}
   295 
   296 
   297 
   298 
   299 EXPORT_C void RMsgQueueBase::NotifyDataAvailable(TRequestStatus& aStatus)
   300 /**
   301 Requests notification when there is at least one message in the queue.
   302 
   303 A thread can have only one data available notification request	outstanding on
   304 this message queue. If a second request is made before
   305 the first request completes, then the calling thread is panicked.
   306 
   307 @param aStatus The request status object to be completed when
   308                a message becomes available.
   309 
   310 @panic KERN-EXEC 47 if a second request is made
   311        while the first request remains outstanding.
   312 */
   313 	{
   314 	aStatus = KRequestPending;
   315 	Exec::MsgQueueNotifyDataAvailable(iHandle, aStatus);
   316 	}
   317 
   318 
   319 
   320 
   321 EXPORT_C void RMsgQueueBase::CancelDataAvailable()
   322 /**
   323 Cancels an outstanding data available notification request.
   324 
   325 If the request is not already complete, then it now completes with KErrCancel.
   326 
   327 @panic KERN-EXEC 50 if attempting to cancel an outstanding request made by
   328        a thread in a different process.
   329        
   330 @see RMsgQueueBase::NotifyDataAvailable
   331 */
   332 	{
   333 	Exec::MsgQueueCancelDataAvailable(iHandle);
   334 	}
   335 
   336 
   337 
   338 
   339 EXPORT_C TInt RMsgQueueBase::MessageSize()
   340 /**
   341 Gets the size of message slots in the queue.
   342 
   343 @return The size of a message slot in the queue.
   344 */
   345 	{
   346 	return Exec::MsgQueueSize(iHandle);
   347 	}
   348 
   349 
   350 
   351 
   352 EXPORT_C TInt RMsgQueueBase::Open(RMessagePtr2 aMessage, TInt aParam, TOwnerType aType)
   353 /**
   354 Opens a global message queue using a handle passed in a server message.
   355 
   356 By default, any thread in the process can use this handle to
   357 access the message queue. However, specifying EOwnerThread as the
   358 third parameter to this function, means that only the opening thread can use
   359 this handle to access the message queue.
   360 
   361 @param aMessage The server message.
   362 @param aParam   The number of the message parameter which holds the handle.
   363 @param aType    The type of handle to be created.
   364 		        EOwnerProcess is the default value, if not explicitly specified.
   365 */
   366 	{
   367 	return SetReturnedHandle(Exec::MessageOpenObject(aMessage.Handle(),EMsgQueue,aParam,aType));
   368 	}
   369 
   370 
   371 
   372 
   373 EXPORT_C TInt RMsgQueueBase::Open(TInt aArgumentIndex, TOwnerType aType)
   374 /**
   375 Opens a message queue using the handle passed in during process creation.
   376 
   377 @param aArgumentIndex The number on the parameter which holds the handle.
   378 @param aType          The type of handle to be created.
   379                       EOwnerProcess is the default value, if not explicitly
   380                       specified.
   381 
   382 @return KErrNone, ifsuccessful;
   383 		KErrArgument, if aArgumentIndex doesn't contain a message queue handle;          
   384 		KErrNotFound, if aArgumentIndex is empty. 
   385 */
   386 	{
   387 	return SetReturnedHandle(Exec::ProcessGetHandleParameter(aArgumentIndex, EMsgQueue, aType));
   388 	}