Changeset 41
- 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
| r36 |
r41 |
|
| 2 | 2 | * David Windsor <dwindsor@tresys.com> |
|---|
| 3 | 3 | * |
|---|
| 4 | | * Copyright (C) 2006, 2007 Tresys Technology, LLC |
|---|
| | 4 | * Copyright (C) 2006 - 2008 Tresys Technology, LLC |
|---|
| 5 | 5 | * Developed Under US JFCOM Sponsorship |
|---|
| 6 | 6 | * |
|---|
| … | … | |
| 41 | 41 | |
|---|
| 42 | 42 | /* 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, |
|---|
| 44 | 44 | * must be the same for the sender and reciever. |
|---|
| 45 | 45 | * role SIPC_CREATOR if this application is the IPC creator, |
|---|
| 46 | 46 | * SIPC_SENDER for the sender and SIPC_RECEIVER |
|---|
| 47 | 47 | * 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 |
|---|
| 49 | 49 | * and reciever. |
|---|
| 50 | | * size Maximum message size to be transmitted. |
|---|
| | 50 | * size Maximum message size to be transmitted. |
|---|
| 51 | 51 | * |
|---|
| 52 | 52 | * 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. |
|---|
| 54 | 54 | */ |
|---|
| 55 | 55 | sipc_t *sipc_open(const char *key, int role, int ipc_type, size_t size); |
|---|
| … | … | |
| 62 | 62 | void sipc_unlink(const char *key, int ipc_type); |
|---|
| 63 | 63 | |
|---|
| 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. |
|---|
| 66 | 66 | * returns 0 on success, <0 on failure */ |
|---|
| 67 | 67 | int sipc_send_data(sipc_t *sipc, int msg_len); |
|---|
| 68 | 68 | |
|---|
| 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 |
|---|
| 70 | 70 | * len will be set to the length. Returns 0 on success, <0 on failure */ |
|---|
| 71 | 71 | int sipc_recv_data(sipc_t *sipc, char **data, int *len); |
|---|
| … | … | |
| 81 | 81 | /* shm specific functions */ |
|---|
| 82 | 82 | |
|---|
| 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. */ |
|---|
| 84 | 87 | int sipc_shm_recv_done(sipc_t *sipc); |
|---|
| 85 | 88 | |
|---|
| r37 |
r41 |
|
| 1 | 1 | /* Author: David Windsor <dwindsor@tresys.com> |
|---|
| 2 | 2 | * |
|---|
| 3 | | * Copyright (C) 2006, 2007 Tresys Technology, LLC |
|---|
| | 3 | * Copyright (C) 2006 - 2008 Tresys Technology, LLC |
|---|
| 4 | 4 | * Developed Under US JFCOM Sponsorship |
|---|
| 5 | 5 | * |
|---|
| r35 |
r41 |
|
| 1 | 1 | /* Author: David Windsor <dwindsor@tresys.com> |
|---|
| 2 | 2 | * |
|---|
| 3 | | * Copyright (C) 2006, 2007 Tresys Technology, LLC |
|---|
| | 3 | * Copyright (C) 2006 - 2008 Tresys Technology, LLC |
|---|
| 4 | 4 | * Developed Under US JFCOM Sponsorship |
|---|
| 5 | 5 | * |
|---|
| r37 |
r41 |
|
| 1 | 1 | /* Author: David Windsor <dwindsor@tresys.com> |
|---|
| 2 | 2 | * |
|---|
| 3 | | * Copyright (C) 2006, 2007 Tresys Technology, LLC |
|---|
| | 3 | * Copyright (C) 2006 - 2008 Tresys Technology, LLC |
|---|
| 4 | 4 | * Developed Under US JFCOM Sponsorship |
|---|
| 5 | 5 | * |
|---|
| … | … | |
| 30 | 30 | #include "mqueue_internal.h" |
|---|
| 31 | 31 | |
|---|
| 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 | */ |
|---|
| 33 | 36 | int sipc_shm_recv_done(sipc_t *sipc) |
|---|
| 34 | 37 | { |
|---|
| 35 | | if (!sipc) |
|---|
| | 38 | if (!sipc || sipc->ipc_type != SIPC_SYSV_SHM) |
|---|
| 36 | 39 | return -1; |
|---|
| 37 | 40 | |
|---|
| 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); |
|---|
| 40 | 43 | return 0; |
|---|
| 41 | 44 | } |
|---|
| r35 |
r41 |
|
| 1 | 1 | /* Author: David Windsor <dwindsor@tresys.com> |
|---|
| 2 | 2 | * |
|---|
| 3 | | * Copyright (C) 2006, 2007 Tresys Technology, LLC |
|---|
| | 3 | * Copyright (C) 2006 - 2008 Tresys Technology, LLC |
|---|
| 4 | 4 | * Developed Under US JFCOM Sponsorship |
|---|
| 5 | 5 | * |
|---|
| r36 |
r41 |
|
| 2 | 2 | * David Windsor <dwindsor@tresys.com> |
|---|
| 3 | 3 | * |
|---|
| 4 | | * Copyright (C) 2006, 2007 Tresys Technology, LLC |
|---|
| | 4 | * Copyright (C) 2006 - 2008 Tresys Technology, LLC |
|---|
| 5 | 5 | * Developed Under US JFCOM Sponsorship |
|---|
| 6 | 6 | * |
|---|
| r37 |
r41 |
|
| 2 | 2 | * David Windsor <dwindsor@tresys.com> |
|---|
| 3 | 3 | * |
|---|
| 4 | | * Copyright (C) 2006, 2007 Tresys Technology, LLC |
|---|
| | 4 | * Copyright (C) 2006 - 2008 Tresys Technology, LLC |
|---|
| 5 | 5 | * Developed Under US JFCOM Sponsorship |
|---|
| 6 | 6 | * |
|---|
| … | … | |
| 29 | 29 | /* Control message types */ |
|---|
| 30 | 30 | #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 |
|---|
| 33 | 34 | #define SIPC_MSG_LEN 0x09 |
|---|
| 34 | 35 | #define SIPC_END_XMIT 0x0c |
|---|
| r37 |
r41 |
|
| 1 | 1 | /* Author: David Windsor <dwindsor@tresys.com> |
|---|
| 2 | 2 | * |
|---|
| 3 | | * Copyright (C) 2006, 2007 Tresys Technology, LLC |
|---|
| | 3 | * Copyright (C) 2006 - 2008 Tresys Technology, LLC |
|---|
| 4 | 4 | * Developed Under US JFCOM Sponsorship |
|---|
| 5 | 5 | * |
|---|
| … | … | |
| 188 | 188 | if (!sipc || !data || !len) |
|---|
| 189 | 189 | 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 | |
|---|
| 190 | 195 | if (sipc->role != SIPC_RECEIVER) { |
|---|
| 191 | 196 | sipc_error(sipc, "sipc_send_data called without receiver flag enabled in IPC structure\n"); |
|---|
| … | … | |
| 198 | 203 | goto err; |
|---|
| 199 | 204 | } |
|---|
| 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 */ |
|---|
| 204 | 205 | |
|---|
| 205 | 206 | /* Receive and validate the length of message marker */ |
|---|
| … | … | |
| 237 | 238 | } |
|---|
| 238 | 239 | |
|---|
| 239 | | *len += recv_sz; |
|---|
| 240 | 240 | while (!is_end_xmit(mbuf)) { |
|---|
| | 241 | *len += recv_sz; |
|---|
| | 242 | |
|---|
| 241 | 243 | /* If this isn't the last packet in the message, |
|---|
| 242 | 244 | * resize to +1 message */ |
|---|
| … | … | |
| 248 | 250 | free(*data); |
|---|
| 249 | 251 | *data = NULL; |
|---|
| | 252 | *len = 0; |
|---|
| 250 | 253 | goto err; |
|---|
| 251 | 254 | } |
|---|
| … | … | |
| 259 | 262 | if ((recv_sz = msgrcv(sipc->msqid, mbuf, SIPC_MQUEUE_MSG_SZ - sizeof(long), SIPC_ANY, 0)) < 0) { |
|---|
| 260 | 263 | 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 | } |
|---|
| 265 | 269 | } |
|---|
| 266 | 270 | |
|---|
| r36 |
r41 |
|
| 1 | 1 | /* Author: David Windsor <dwindsor@tresys.com> |
|---|
| 2 | 2 | * |
|---|
| 3 | | * Copyright (C) 2006, 2007 Tresys Technology, LLC |
|---|
| | 3 | * Copyright (C) 2006 - 2008 Tresys Technology, LLC |
|---|
| 4 | 4 | * Developed Under US JFCOM Sponsorship |
|---|
| 5 | 5 | * |
|---|
| r37 |
r41 |
|
| 1 | 1 | /* Author: David Windsor <dwindsor@tresys.com> |
|---|
| 2 | 2 | * |
|---|
| 3 | | * Copyright (C) 2006, 2007 Tresys Technology, LLC |
|---|
| | 3 | * Copyright (C) 2006 - 2008 Tresys Technology, LLC |
|---|
| 4 | 4 | * Developed Under US JFCOM Sponsorship |
|---|
| 5 | 5 | * |
|---|
| … | … | |
| 78 | 78 | goto err; |
|---|
| 79 | 79 | |
|---|
| 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) |
|---|
| 82 | 82 | goto err; |
|---|
| 83 | 83 | |
|---|
| … | … | |
| 151 | 151 | } |
|---|
| 152 | 152 | |
|---|
| 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. |
|---|
| 165 | 159 | */ |
|---|
| 166 | 160 | int sipc_shm_send_data(sipc_t *sipc, int msg_len) |
|---|
| … | … | |
| 168 | 162 | if (!sipc) |
|---|
| 169 | 163 | 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 | | } |
|---|
| 176 | 164 | |
|---|
| 177 | 165 | /* Send a DATA_READY marker */ |
|---|
| … | … | |
| 181 | 169 | } |
|---|
| 182 | 170 | |
|---|
| 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 | */ |
|---|
| 196 | 192 | int sipc_shm_recv_data(sipc_t *sipc, char **data, int *len) |
|---|
| 197 | 193 | { |
|---|
| … | … | |
| 205 | 201 | |
|---|
| 206 | 202 | /* 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); |
|---|
| 208 | 204 | if (mtype == SIPC_DATA_READY) { |
|---|
| 209 | 205 | /* It is now OK to read shared memory */ |
|---|
| … | … | |
| 215 | 211 | return -1; |
|---|
| 216 | 212 | } |
|---|
| 217 | | |
|---|
| 218 | | return 0; |
|---|
| 219 | | } |
|---|
| | 213 | } |
|---|
| r36 |
r41 |
|
| 1 | 1 | /* Author: David Windsor <dwindsor@tresys.com> |
|---|
| 2 | 2 | * |
|---|
| 3 | | * Copyright (C) 2006, 2007 Tresys Technology, LLC |
|---|
| | 3 | * Copyright (C) 2006 - 2008 Tresys Technology, LLC |
|---|
| 4 | 4 | * Developed Under US JFCOM Sponsorship |
|---|
| 5 | 5 | * |
|---|
Download in other formats:
* Generating other formats may take time.