kernel/eka/euser/us_mqueue.cpp
changeset 0 a41df078684a
equal deleted inserted replaced
-1:000000000000 0:a41df078684a
       
     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 	}