Changeset 41

Show
Ignore:
Timestamp:
06/04/08 16:51:33 (6 months ago)
Author:
jtang
Message:

Updated copyright notices.
Split NOP into DATA_READING and DATA_DONE, to better reflect its role within the state machine.
Improved error code paths.
Fixed calculation of message size when receiving from a message queue.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/libsipc/include/sipc/sipc.h

    r36 r41  
    22*          David Windsor <dwindsor@tresys.com> 
    33* 
    4 * Copyright (C) 2006, 2007 Tresys Technology, LLC 
     4* Copyright (C) 2006 - 2008 Tresys Technology, LLC 
    55* Developed Under US JFCOM Sponsorship 
    66* 
     
    4141 
    4242/* sipc_open(char *key, int role, int ipc_type, size_t size) 
    43  *    key             Unique key to identify IPC communication channel, 
     43 *    key             Unique key to identify IPC communication channel, 
    4444 *                      must be the same for the sender and reciever. 
    4545 *      role            SIPC_CREATOR if this application is the IPC creator, 
    4646 *                      SIPC_SENDER for the sender and SIPC_RECEIVER 
    4747 *                      for the reciever 
    48  *     ipc_type        Which IPC type used, must be the same for sender  
     48 *     ipc_type        Which IPC type used, must be the same for sender 
    4949 *                      and reciever. 
    50  *     size           Maximum message size to be transmitted. 
     50 *     size           Maximum message size to be transmitted. 
    5151 * 
    5252 *      sipc_open must be called before any other function to initialize 
    53  *    the sipc_t struct.  Caller must call sipc_close to free the memory. 
     53 *    the sipc_t struct.  Caller must call sipc_close to free the memory. 
    5454 */ 
    5555sipc_t *sipc_open(const char *key, int role, int ipc_type, size_t size); 
     
    6262void sipc_unlink(const char *key, int ipc_type); 
    6363 
    64 /* Blocking call to send msglen bytes of data.  
    65  * This can only be called if sender was specified when sipc_init was called.  
     64/* Blocking call to send msglen bytes of data. 
     65 * This can only be called if sender was specified when sipc_init was called. 
    6666 * returns 0 on success, <0 on failure */ 
    6767int sipc_send_data(sipc_t *sipc, int msg_len); 
    6868 
    69 /* Blocking call to recieve data. Data will be allocated and filled and 
     69/* Blocking call to recieve data. Data will be allocated and filled and 
    7070 * len will be set to the length. Returns 0 on success, <0 on failure */ 
    7171int sipc_recv_data(sipc_t *sipc, char **data, int *len); 
     
    8181/* shm specific functions */ 
    8282 
    83 /* Receiver calls this when it is done receiving a message in shared memory */ 
     83/* Receiver calls this when it is done receiving a message in shared 
     84 * memory.  There must be exactly one call to sipc_shm_recv_done() for 
     85 * every call to sipc_recv_data(), if the sipc was created as shared 
     86 * memory. */ 
    8487int sipc_shm_recv_done(sipc_t *sipc); 
    8588 
  • trunk/libsipc/src/mqueue_internal.c

    r37 r41  
    11/* Author: David Windsor <dwindsor@tresys.com> 
    22* 
    3 * Copyright (C) 2006, 2007 Tresys Technology, LLC 
     3* Copyright (C) 2006 - 2008 Tresys Technology, LLC 
    44* Developed Under US JFCOM Sponsorship 
    55* 
  • trunk/libsipc/src/mqueue_internal.h

    r35 r41  
    11/* Author: David Windsor <dwindsor@tresys.com> 
    22* 
    3 * Copyright (C) 2006, 2007 Tresys Technology, LLC 
     3* Copyright (C) 2006 - 2008 Tresys Technology, LLC 
    44* Developed Under US JFCOM Sponsorship 
    55* 
  • trunk/libsipc/src/shm_internal.c

    r37 r41  
    11/* Author: David Windsor <dwindsor@tresys.com> 
    22* 
    3 * Copyright (C) 2006, 2007 Tresys Technology, LLC 
     3* Copyright (C) 2006 - 2008 Tresys Technology, LLC 
    44* Developed Under US JFCOM Sponsorship 
    55* 
     
    3030#include "mqueue_internal.h" 
    3131 
    32 /* Receive NOP messages, which will unblock the sender */ 
     32/* When called by the reader, this should clear out the message queue. 
     33 * This will then unblock the writer, so that the writer can safely 
     34 * modify the shared memory buffer. 
     35 */ 
    3336int sipc_shm_recv_done(sipc_t *sipc) 
    3437{ 
    35         if (!sipc
     38        if (!sipc || sipc->ipc_type != SIPC_SYSV_SHM
    3639                return -1; 
    3740 
    38         mqueue_get_msg_type(sipc->s.msqid, SIPC_NOP, MQ_BLOCK); 
    39         mqueue_get_msg_type(sipc->s.msqid, SIPC_NOP, MQ_BLOCK); 
     41        mqueue_get_msg_type(sipc->s.msqid, SIPC_DATA_READING, MQ_BLOCK); 
     42        mqueue_get_msg_type(sipc->s.msqid, SIPC_DATA_DONE, MQ_BLOCK); 
    4043        return 0; 
    4144} 
  • trunk/libsipc/src/shm_internal.h

    r35 r41  
    11/* Author: David Windsor <dwindsor@tresys.com> 
    22* 
    3 * Copyright (C) 2006, 2007 Tresys Technology, LLC 
     3* Copyright (C) 2006 - 2008 Tresys Technology, LLC 
    44* Developed Under US JFCOM Sponsorship 
    55* 
  • trunk/libsipc/src/sipc.c

    r36 r41  
    22*          David Windsor <dwindsor@tresys.com> 
    33* 
    4 * Copyright (C) 2006, 2007 Tresys Technology, LLC 
     4* Copyright (C) 2006 - 2008 Tresys Technology, LLC 
    55* Developed Under US JFCOM Sponsorship 
    66* 
  • trunk/libsipc/src/sipc_internal.h

    r37 r41  
    22*          David Windsor <dwindsor@tresys.com> 
    33* 
    4 * Copyright (C) 2006, 2007 Tresys Technology, LLC 
     4* Copyright (C) 2006 - 2008 Tresys Technology, LLC 
    55* Developed Under US JFCOM Sponsorship 
    66* 
     
    2929/* Control message types */ 
    3030#define SIPC_ANY        0x00 
    31 #define SIPC_DATA_READY 0x03 
    32 #define SIPC_NOP        0x06 
     31#define SIPC_DATA_READY         0x03 
     32#define SIPC_DATA_READING       0x04 
     33#define SIPC_DATA_DONE          0x05 
    3334#define SIPC_MSG_LEN    0x09 
    3435#define SIPC_END_XMIT   0x0c 
  • trunk/libsipc/src/sipc_mqueue.c

    r37 r41  
    11/* Author: David Windsor <dwindsor@tresys.com> 
    22* 
    3 * Copyright (C) 2006, 2007 Tresys Technology, LLC 
     3* Copyright (C) 2006 - 2008 Tresys Technology, LLC 
    44* Developed Under US JFCOM Sponsorship 
    55* 
     
    188188        if (!sipc || !data || !len) 
    189189                goto err; 
     190 
     191        *data = NULL;                  /* Pointer to a buffer created here */ 
     192        idx = 0;                       /* Current index into the buffer */ 
     193        *len = 0;                      /* Bytes received so far */ 
     194 
    190195        if (sipc->role != SIPC_RECEIVER) { 
    191196                sipc_error(sipc, "sipc_send_data called without receiver flag enabled in IPC structure\n"); 
     
    198203                goto err; 
    199204        } 
    200  
    201         *data = NULL;                  /* Pointer to a buffer created here */ 
    202         idx = 0;                       /* Current index into the buffer */ 
    203         *len = 0;                      /* Bytes received so far */ 
    204205 
    205206        /* Receive and validate the length of message marker */ 
     
    237238        } 
    238239 
    239         *len += recv_sz; 
    240240        while (!is_end_xmit(mbuf)) { 
     241                *len += recv_sz; 
     242 
    241243                /* If this isn't the last packet in the message, 
    242244                 * resize to +1 message */ 
     
    248250                        free(*data); 
    249251                        *data = NULL; 
     252                        *len = 0; 
    250253                        goto err; 
    251254                } 
     
    259262                if ((recv_sz = msgrcv(sipc->msqid, mbuf, SIPC_MQUEUE_MSG_SZ - sizeof(long), SIPC_ANY, 0)) < 0) { 
    260263                        sipc_error(sipc, "msgrcv: %s\n", strerror(errno)); 
    261                         goto err; 
    262                 } 
    263  
    264                 *len += recv_sz; 
     264                        free(*data); 
     265                        *data = NULL; 
     266                        *len = 0; 
     267                        goto err; 
     268                } 
    265269        } 
    266270 
  • trunk/libsipc/src/sipc_mqueue.h

    r36 r41  
    11/* Author: David Windsor <dwindsor@tresys.com> 
    22* 
    3 * Copyright (C) 2006, 2007 Tresys Technology, LLC 
     3* Copyright (C) 2006 - 2008 Tresys Technology, LLC 
    44* Developed Under US JFCOM Sponsorship 
    55* 
  • trunk/libsipc/src/sipc_shm.c

    r37 r41  
    11/* Author: David Windsor <dwindsor@tresys.com> 
    22* 
    3 * Copyright (C) 2006, 2007 Tresys Technology, LLC 
     3* Copyright (C) 2006 - 2008 Tresys Technology, LLC 
    44* Developed Under US JFCOM Sponsorship 
    55* 
     
    7878                goto err; 
    7979 
    80         /* Set capacity of side channel to 3 messages */ 
    81         if (mqueue_set_capacity(sipc->s.msqid, 3) < 0) 
     80        /* Set capacity of side channel to only 1 message */ 
     81        if (mqueue_set_capacity(sipc->s.msqid, 1) < 0) 
    8282                goto err; 
    8383 
     
    151151} 
    152152 
    153 /* Send a NOP, then the data, then another NOP.  This is because after 
    154  * the data is received, there will be 2 NOPs still in the queue.  A 
    155  * subsequent send will then add a NOP, but then block on DATA_READY 
    156  * until sipc_shm_recv_done() is called. 
    157  * 
    158  * NOPs are needed because there is a potential race condition.  A 
    159  * reader could receive a message, but not have time to copy the data 
    160  * before the writer sends another message. 
    161  * 
    162  * Keeping NOPs, but decreasing the queue size to 1 will also not 
    163  * work.  This is because the writer should be able to send at least 
    164  * one message without blocking itself. 
     153/* The order of signals from the writer to reader is DATA_READY, 
     154 * DATA_READING, and then DATA_DONE.  The writer, running in a 
     155 * different process than the reader, is to block between READY and 
     156 * READING, and then between READING and DONE.  This is to prevent 
     157 * race conditions where the writer modifies the shared memory buffer 
     158 * before the reader is done with the data. 
    165159 */ 
    166160int sipc_shm_send_data(sipc_t *sipc, int msg_len) 
     
    168162        if (!sipc) 
    169163                return -1; 
    170  
    171         /* Send a NULL marker; this should block at first */ 
    172         if (mqueue_send_msg_type(sipc->s.msqid, SIPC_NOP, MQ_BLOCK) < 0) { 
    173                 sipc_error(sipc, "Could not send NOP marker\n"); 
    174                 return -1; 
    175         } 
    176164 
    177165        /* Send a DATA_READY marker */ 
     
    181169        } 
    182170 
    183         /* Send another NULL marker */ 
    184         if (mqueue_send_msg_type(sipc->s.msqid, SIPC_NOP, MQ_BLOCK) < 0) { 
    185                 sipc_error(sipc, "Could not send NOP marker\n"); 
    186                 return -1; 
    187         } 
    188  
    189         return 0; 
    190 
    191  
    192 /* Receive a DATA_READY marker from sender and pass 
    193  * the shm pointer to the caller. 
    194  * This function will block if the DATA_READY marker is not 
    195  * present on the queue. */ 
     171        /* Send a DATA_READING marker; this should block until the 
     172           reader calls sipc_recv_data(). */ 
     173        if (mqueue_send_msg_type(sipc->s.msqid, SIPC_DATA_READING, MQ_BLOCK) < 0) { 
     174                sipc_error(sipc, "Could not send DATA_READING marker\n"); 
     175                return -1; 
     176        } 
     177 
     178        /* Send a DATA_DONE marker; this should block until the reader 
     179           calls sipc_shm_recv_done(). */ 
     180        if (mqueue_send_msg_type(sipc->s.msqid, SIPC_DATA_DONE, MQ_BLOCK) < 0) { 
     181                sipc_error(sipc, "Could not send DATA_DONE marker\n"); 
     182                return -1; 
     183        } 
     184 
     185        return 0; 
     186
     187 
     188/* Receive a DATA_READY marker from sender and pass the shm pointer to 
     189 * the caller.  This function will block if there is nothing on the 
     190 * message queue. 
     191 */ 
    196192int sipc_shm_recv_data(sipc_t *sipc, char **data, int *len) 
    197193{ 
     
    205201 
    206202        /* Get a message from the side channel. */ 
    207         mtype = mqueue_get_msg_type(sipc->s.msqid, SIPC_DATA_READY, MQ_BLOCK); 
     203        mtype = mqueue_get_msg_type(sipc->s.msqid, SIPC_ANY, MQ_BLOCK); 
    208204        if (mtype == SIPC_DATA_READY) { 
    209205                /* It is now OK to read shared memory */ 
     
    215211                return -1; 
    216212        } 
    217  
    218         return 0; 
    219 
     213
  • trunk/libsipc/src/sipc_shm.h

    r36 r41  
    11/* Author: David Windsor <dwindsor@tresys.com> 
    22* 
    3 * Copyright (C) 2006, 2007 Tresys Technology, LLC 
     3* Copyright (C) 2006 - 2008 Tresys Technology, LLC 
    44* Developed Under US JFCOM Sponsorship 
    55*