00001 /* 00002 Copyright (c) 2007-2010 Nokia Corporation and/or its subsidiary(-ies). All rights reserved. 00003 00004 Redistribution and use in source and binary forms, with or without 00005 modification, are permitted provided that the following conditions are met: 00006 00007 * Redistributions of source code must retain the above copyright notice, this 00008 list of conditions and the following disclaimer. 00009 * Redistributions in binary form must reproduce the above copyright notice, 00010 this list of conditions and the following disclaimer in the documentation 00011 and/or other materials provided with the distribution. 00012 * Neither the name of Nokia Corporation nor the names of its contributors 00013 may be used to endorse or promote products derived from this software 00014 without specific prior written permission. 00015 00016 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 00017 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 00018 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 00019 DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 00020 FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 00021 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 00022 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 00023 CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 00024 OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00025 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00026 00027 Description: 00028 */ 00029 00030 00031 #include <errno.h> 00032 #include <sys/msg.h> 00033 #include <sys/sem.h> 00034 #include "MsgQInternal.h" 00035 00036 00037 /******************************************************************************** 00038 * MsgQCreate 00039 * Description: Creates a message queue 00040 * Inputs: 00041 * qName : ULONG that represents the queue name 00042 * maxMsgs : ULONG that represents maximum size of messages 00043 *********************************************************************************/ 00044 EXPORT_C int MsgQCreate(ULONG qName, ULONG maxMsgs, ULONG qOptions, int* err) { 00045 int qId; 00046 int semId; 00047 int semName ; 00048 struct msqid_ds qStatus ; 00049 struct semid_ds sStatus ; 00050 00051 union semun { 00052 int val; 00053 struct semid_ds* buf; 00054 ushort_t* array; 00055 } arg ; 00056 00057 00058 int hashInstErr; 00059 00060 if (MsgQTableLookup(qName) != NULL) { 00061 *err = OK; 00062 return (OK); 00063 } 00064 else { 00065 if((qOptions == MSG_Q_FIFO) || (qOptions == MSG_Q_PRIORITY)) { 00066 // Set msg queue options to FIFO and create the message queue 00067 qOptions= MSG_Q_FIFO ; 00068 if((qId = msgget((key_t) qName ,IPC_CREAT | 0666 | IPC_EXCL )) >=0 ) { 00069 // set msg queue parameter max # bytes in queue 00070 if( msgctl(qId,IPC_STAT,&qStatus) == 0 ) 00071 if( qStatus.msg_qbytes > (maxMsgs * MAX_MSG_LEN) ) { 00072 qStatus.msg_qbytes = maxMsgs * MAX_MSG_LEN ; 00073 if( msgctl(qId,IPC_SET,&qStatus) < 0) { 00074 // delete message queue on error 00075 msgctl(qId,IPC_RMID,0); 00076 *err = errno; 00077 return(ERROR); 00078 } 00079 } 00080 // create semaphore 00081 semName= (key_t) qName; 00082 if((semId = semget(semName, 1, IPC_CREAT | 0666 |IPC_EXCL )) >= 0 ) { 00083 // set the semaphore value 00084 arg.buf = &sStatus; 00085 arg.val = 1; 00086 semctl(semId , 0, SETVAL, arg) ; 00087 00088 //install queue data in hash table 00089 if(InstallMsqQTable(qName, qId, semId, &hashInstErr) == OK) { 00090 AddToMsgQTable(qName); 00091 *err = OK; 00092 return (OK); 00093 } 00094 else { 00095 //delete semaphore on error 00096 semctl(semId,0,IPC_RMID,0) ; 00097 *err = hashInstErr; 00098 } 00099 } 00100 else { 00101 // delete message queue on error 00102 msgctl(qId,IPC_RMID,0); 00103 *err = errno; 00104 } 00105 } 00106 else { 00107 *err = errno; 00108 } 00109 } 00110 else 00111 *err = KMsgQLibParamErr; 00112 00113 return(ERROR); 00114 } 00115 } 00116