18 static unsigned _cisChannelsCreated = 0;
20 #define _cisTrackChannels 256 22 static int _cisChannelNames[_cisTrackChannels];
25 static unsigned _cisChannelsUsed = 0;
26 static unsigned _ipc_rand_seeded = 0;
31 typedef struct msgbuf_t {
33 char data[CIS_MSG_MAX];
42 int check_channels(
comm_t comm) {
44 if (strlen(comm.
name) == 0) {
45 cislog_error(
"Cannot create channel with empty name.");
51 for (i = 0; i < _cisChannelsUsed; i++ ) {
52 if (_cisChannelNames[i] == atoi(comm.
address)) {
54 cislog_error(
"Attempt to re-use channel: name=%s, key=%s, i=%d",
60 if (_cisChannelsUsed >= _cisTrackChannels) {
61 cislog_error(
"Too many channels in use, max: %d", _cisTrackChannels);
72 void add_channel(
const comm_t comm) {
74 _cisChannelNames[_cisChannelsUsed++] = atoi(comm.
address);
86 int remove_comm(
const comm_t comm,
const int close_comm) {
89 ret = msgctl(((
int*)comm.
handle)[0], IPC_RMID, NULL);
98 for (i = 0; i < _cisChannelsUsed; i++) {
99 if (ich == _cisChannelNames[i]) {
100 memmove(_cisChannelNames + i, _cisChannelNames + i + 1,
101 (_cisTrackChannels - (i + 1))*
sizeof(
int));
108 cislog_error(
"remove_comm(%s): Could not locate comm in register.", comm.
name);
124 int new_ipc_address(
comm_t *comm) {
128 if (!(_ipc_rand_seeded)) {
129 srand(ptr2seed(comm));
130 _ipc_rand_seeded = 1;
135 if (strlen(comm->
name) == 0) {
136 sprintf(comm->
name,
"tempnewIPC.%d", key);
138 ret = check_channels(*comm);
142 sprintf(comm->
address,
"%d", key);
143 int *fid = (
int*)malloc(
sizeof(
int));
145 cislog_error(
"new_ipc_address: Could not malloc queue fid.");
148 fid[0] = msgget(key, (IPC_CREAT | 0777));
150 cislog_error(
"new_ipc_address: msgget(%d, %d | 0777) ret(%d), errno(%d): %s",
151 key, IPC_CREAT, fid[0], errno, strerror(errno));
154 comm->
handle = (
void*)fid;
156 _cisChannelsCreated++;
166 int init_ipc_comm(
comm_t *comm) {
167 if (comm->
valid == 0)
169 if (strlen(comm->
name) == 0) {
170 sprintf(comm->
name,
"tempinitIPC.%s", comm->
address);
172 int ret = check_channels(*comm);
177 int qkey = atoi(comm->
address);
178 int *fid = (
int *)malloc(
sizeof(
int));
180 cislog_error(
"init_ipc_comm: Could not malloc queue fid.");
183 fid[0] = msgget(qkey, 0600);
185 cislog_error(
"init_ipc_address: msgget(%d, 0600) ret(%d), errno(%d): %s",
186 qkey, fid[0], errno, strerror(errno));
189 comm->
handle = (
void*)fid;
199 int free_ipc_comm(
comm_t *x) {
218 int ipc_comm_nmsg(
const comm_t x) {
221 cislog_error(
"ipc_comm_nmsg: Queue handle is NULL.");
224 int rc = msgctl(((
int*)x.
handle)[0], IPC_STAT, &buf);
229 int ret = buf.msg_qnum;
243 int ipc_comm_send(
const comm_t x,
const char *data,
const size_t len) {
244 cislog_debug(
"ipc_comm_send(%s): %d bytes", x.
name, len);
245 if (comm_base_send(x, data, len) == -1)
249 memcpy(t.data, data, len);
251 int handle = ((
int*)(x.
handle))[0];
253 ret = msgsnd(handle, &t, len, IPC_NOWAIT);
254 cislog_debug(
"ipc_comm_send(%s): msgsnd returned %d", x.
name, ret);
256 if ((ret == -1) && (errno == EAGAIN)) {
257 cislog_debug(
"ipc_comm_send(%s): msgsnd, sleep", x.
name);
258 usleep(CIS_SLEEP_TIME);
260 cislog_error(
"ipc_comm_send: msgsend(%d, %p, %d, IPC_NOWAIT) ret(%d), errno(%d): %s",
261 (
int*)x.
handle, &t, len, ret, errno, strerror(errno));
266 cislog_debug(
"ipc_comm_send(%s): returning %d", x.
name, ret);
283 int ipc_comm_recv(
const comm_t x,
char **data,
const size_t len,
284 const int allow_realloc) {
285 cislog_debug(
"ipc_comm_recv(%s)", x.
name);
291 ret = msgrcv(((
int*)x.
handle)[0], &t, CIS_MSG_MAX, 0, IPC_NOWAIT);
292 if (ret == -1 && errno == ENOMSG) {
293 cislog_debug(
"ipc_comm_recv(%s): no input, sleep", x.
name);
294 usleep(CIS_SLEEP_TIME);
296 cislog_debug(
"ipc_comm_recv(%s): received input: %d bytes, ret=%d",
297 x.
name, strlen(t.data), ret);
302 cislog_debug(
"ipc_comm_recv: msgrecv(%d, %p, %d, 0, IPC_NOWAIT): %s",
303 (
int*)x.
handle, &t, (
int)CIS_MSG_MAX, strerror(errno));
307 if (len_recv > (
int)len) {
309 cislog_debug(
"ipc_comm_recv(%s): reallocating buffer from %d to %d bytes.",
310 x.
name, (
int)len, len_recv);
311 (*data) = (
char*)realloc(*data, len_recv);
313 cislog_error(
"ipc_comm_recv(%s): failed to realloc buffer.", x.
name);
317 cislog_error(
"ipc_comm_recv(%s): buffer (%d bytes) is not large enough for message (%d bytes)",
318 x.
name, len, len_recv);
319 return -(len_recv - 1);
322 memcpy(*data, t.data, len_recv);
323 (*data)[len_recv - 1] =
'\0';
325 cislog_debug(
"ipc_comm_recv(%s): returns %d bytes", x.
name, ret);
341 int ipc_comm_send_nolimit(
const comm_t x,
const char *data,
const size_t len){
342 cislog_debug(
"ipc_comm_send_nolimit(%s): %d bytes", x.
name, len);
345 char msg[CIS_MSG_MAX];
346 sprintf(msg,
"%ld", (
long)(len));
347 ret = ipc_comm_send(x, msg, strlen(msg));
349 cislog_debug(
"ipc_comm_send_nolimit(%s): sending size of payload failed.", x.
name);
354 if ((len - prev) > CIS_MSG_MAX)
355 msgsiz = CIS_MSG_MAX;
358 ret = ipc_comm_send(x, data + prev, msgsiz);
360 cislog_debug(
"ipc_comm_send_nolimit(%s): send interupted at %d of %d bytes.",
361 x.
name, (
int)prev, (
int)len);
365 cislog_debug(
"ipc_comm_send_nolimit(%s): %d of %d bytes sent",
369 cislog_debug(
"ipc_comm_send_nolimit(%s): %d bytes completed", x.
name, len);
381 void ipc_install_error() {
382 cislog_error(
"Compiler flag 'IPCINSTALLED' not defined so IPC bindings are disabled.");
391 int free_ipc_comm(
comm_t *x) {
406 int new_ipc_address(
comm_t *comm) {
421 int init_ipc_comm(
comm_t *comm) {
436 int ipc_comm_nmsg(
const comm_t x) {
455 int ipc_comm_send(
const comm_t x,
const char *data,
const size_t len) {
479 int ipc_comm_recv(
const comm_t x,
char **data,
const size_t len,
480 const int allow_realloc) {
void * handle
Pointer to handle for comm.
Definition: CommBase.h:25
Communication structure.
Definition: CommBase.h:19
char address[COMM_ADDRESS_SIZE]
Comm address.
Definition: CommBase.h:22
char direction[COMM_DIR_SIZE]
send or recv for direction messages will go.
Definition: CommBase.h:23
char name[COMM_NAME_SIZE]
Comm name.
Definition: CommBase.h:21
int valid
1 if communicator initialized, 0 otherwise.
Definition: CommBase.h:24