Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members

MessageQueue.cc

Go to the documentation of this file.
00001 /*
00002  * MessageQueue.cc
00003  *
00004  * Smalltalk like class library for C++
00005  * Message queue accessor.
00006  *
00007  * Copyright (c) 2003 Martin Dvorak, Milan Cermak
00008  */
00009 /*
00010  * This library is free software; you can redistribute it and/or
00011  * modify it under the terms of the GNU Lesser General Public
00012  * License as published by the Free Software Foundation; either
00013  * version 2.1 of the License, or (at your option) any later version.
00014  *
00015  * This library is distributed in the hope that it will be useful,
00016  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00018  * Lesser General Public License for more details.
00019  *
00020  * You should have received a copy of the GNU Lesser General Public
00021  * License along with this library; if not, write to the Free Software
00022  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00023  */
00024 #include <stdio.h>
00025 #include <sys/types.h>
00026 #include <sys/ipc.h>
00027 #include <sys/msg.h>
00028 #include <stdlib.h>
00029 #include <string.h>
00030 #include <errno.h>
00031 
00032 #include <stlib/os/MessageQueue.h>
00033 #include <stlib/ByteArray.h>
00034 #include <stlib/String.h>
00035 #include "ipckey.h"
00036 
00037 #define MAXBUFFERLEN 256
00038 
00039 using namespace OS;
00040 
00041 /* Attach message queue with given key */
00042 MessageQueue::MessageQueue(int queueKey, bool exclusive)
00043 {
00044     int flags = 0664 | IPC_CREAT;
00045 
00046     if (exclusive)
00047         flags = flags | IPC_EXCL;
00048     queueid = msgget(queueKey, flags);
00049     queueCreationKey = queueKey;
00050     if (queueid >= 0) active = true;
00051     _priority = 1;
00052 }
00053 
00054 MessageQueue *MessageQueue::open(void)
00055 {
00056     return MessageQueue::open(new String("stlib-MessageQueue"));
00057 }
00058 
00059 MessageQueue *MessageQueue::open(bool exclusive)
00060 {
00061     return MessageQueue::open(new String("stlib-MessageQueue"), exclusive);
00062 }
00063 
00064 MessageQueue *MessageQueue::open(String *key, bool exclusive)
00065 {
00066     return new MessageQueue(getkey(key->asCString()), exclusive);
00067 }
00068 
00069 /* Accessing protocol */
00070 long MessageQueue::bufferSize(void)
00071 {
00072     return MAXBUFFERLEN;
00073 }
00074 
00075 void MessageQueue::priority(long level)
00076 {
00077     _priority = level;
00078 }
00079 
00080 long MessageQueue::priority(void)
00081 {
00082     return _priority;
00083 }
00084 
00085 /* Close active message queue */
00086 void MessageQueue::close(void)
00087 {
00088     if (active)
00089         msgctl(queueid, IPC_RMID, NULL);
00090     active = false;
00091 }
00092 
00093 /* Data transfer protocol */
00094 int MessageQueue::readInto(ByteArray *buffer, long startIndex, long count)
00095 {
00096     int bytes;
00097     struct msgbuf {
00098         long mtype;
00099         unsigned char data[MAXBUFFERLEN];
00100     } buf;
00101 
00102     if (queueid < 0) return 0;
00103     if (count > MAXBUFFERLEN) count = MAXBUFFERLEN;
00104 
00105     bytes = msgrcv(queueid, &buf, count, 0, MSG_NOERROR);
00106     if (bytes > 0)
00107         buffer->replace(startIndex, startIndex+bytes, buf.data);
00108     return bytes;
00109 }
00110 
00111 int MessageQueue::writeFrom(ByteArray *buffer, long startIndex, long count)
00112 {
00113     struct msgbuf {
00114         long mtype;
00115         unsigned char mtext[MAXBUFFERLEN];
00116     } buf;
00117 
00118     if (queueid < 0 || count < 1)
00119         return 0;
00120 
00121     if (count > MAXBUFFERLEN) count = MAXBUFFERLEN;
00122     buf.mtype = _priority;
00123     /* Must memcpy, pointer doesn't work. */
00124     memcpy(buf.mtext, &(buffer->rawBytesReadOnly())[startIndex], count);
00125     int error = msgsnd(queueid, &buf, count, 0);
00126     if (error < 0)
00127         perror(__PRETTY_FUNCTION__);
00128 
00129     return (error < 0) ? 0 : count;
00130 }
00131 
00132 /* Positioning protocol */
00133 void MessageQueue::seekTo(long position)
00134 {
00135     shouldNotImplement(new String(__PRETTY_FUNCTION__));
00136 }

Generated on Mon Nov 27 09:47:55 2006 for Smalltalk like C++ Class Library by  doxygen 1.4.2