22 static unsigned _cisChannelsCreated = 0;
24 #define _cisTrackChannels 256 26 static int _cisChannelNames[_cisTrackChannels];
29 static unsigned _cisChannelsUsed = 0;
30 static unsigned _ipc_rand_seeded = 0;
35 typedef struct msgbuf_t {
37 char data[CIS_MSG_MAX];
46 int check_channels(
comm_t comm) {
48 if (strlen(comm.
name) == 0) {
49 cislog_error(
"Cannot create channel with empty name.");
55 for (i = 0; i < _cisChannelsUsed; i++ ) {
56 if (_cisChannelNames[i] == atoi(comm.
address)) {
58 cislog_error(
"Attempt to re-use channel: name=%s, key=%s, i=%d",
64 if (_cisChannelsUsed >= _cisTrackChannels) {
65 cislog_error(
"Too many channels in use, max: %d", _cisTrackChannels);
76 void add_channel(
const comm_t comm) {
78 _cisChannelNames[_cisChannelsUsed++] = atoi(comm.
address);
90 int remove_comm(
const comm_t comm,
const int close_comm) {
93 ret = msgctl(((
int*)comm.
handle)[0], IPC_RMID, NULL);
102 for (i = 0; i < _cisChannelsUsed; i++) {
103 if (ich == _cisChannelNames[i]) {
104 memmove(_cisChannelNames + i, _cisChannelNames + i + 1,
105 (_cisTrackChannels - (i + 1))*
sizeof(
int));
112 cislog_error(
"remove_comm(%s): Could not locate comm in register.", comm.
name);
128 int new_ipc_address(
comm_t *comm) {
132 if (!(_ipc_rand_seeded)) {
133 srand(ptr2seed(comm));
134 _ipc_rand_seeded = 1;
139 if (strlen(comm->
name) == 0) {
140 sprintf(comm->
name,
"tempnewIPC.%d", key);
142 ret = check_channels(*comm);
146 sprintf(comm->
address,
"%d", key);
147 int *fid = (
int*)malloc(
sizeof(
int));
149 cislog_error(
"new_ipc_address: Could not malloc queue fid.");
152 fid[0] = msgget(key, (IPC_CREAT | 0777));
154 cislog_error(
"new_ipc_address: msgget(%d, %d | 0777) ret(%d), errno(%d): %s",
155 key, IPC_CREAT, fid[0], errno, strerror(errno));
158 comm->
handle = (
void*)fid;
160 _cisChannelsCreated++;
170 int init_ipc_comm(
comm_t *comm) {
171 if (comm->
valid == 0)
173 if (strlen(comm->
name) == 0) {
174 sprintf(comm->
name,
"tempinitIPC.%s", comm->
address);
176 int ret = check_channels(*comm);
181 int qkey = atoi(comm->
address);
182 int *fid = (
int *)malloc(
sizeof(
int));
184 cislog_error(
"init_ipc_comm: Could not malloc queue fid.");
187 fid[0] = msgget(qkey, 0600);
189 cislog_error(
"init_ipc_address: msgget(%d, 0600) ret(%d), errno(%d): %s",
190 qkey, fid[0], errno, strerror(errno));
193 comm->
handle = (
void*)fid;
203 int free_ipc_comm(
comm_t *x) {
222 int ipc_comm_nmsg(
const comm_t x) {
225 cislog_error(
"ipc_comm_nmsg: Queue handle is NULL.");
228 int rc = msgctl(((
int*)x.
handle)[0], IPC_STAT, &buf);
233 int ret = buf.msg_qnum;
247 int ipc_comm_send(
const comm_t x,
const char *data,
const size_t len) {
248 cislog_debug(
"ipc_comm_send(%s): %d bytes", x.
name, len);
249 if (comm_base_send(x, data, len) == -1)
253 memcpy(t.data, data, len);
255 int handle = ((
int*)(x.
handle))[0];
257 ret = msgsnd(handle, &t, len, IPC_NOWAIT);
258 cislog_debug(
"ipc_comm_send(%s): msgsnd returned %d", x.
name, ret);
260 if ((ret == -1) && (errno == EAGAIN)) {
261 cislog_debug(
"ipc_comm_send(%s): msgsnd, sleep", x.
name);
262 usleep(CIS_SLEEP_TIME);
264 cislog_error(
"ipc_comm_send: msgsend(%d, %p, %d, IPC_NOWAIT) ret(%d), errno(%d): %s",
265 (
int*)x.
handle, &t, len, ret, errno, strerror(errno));
270 cislog_debug(
"ipc_comm_send(%s): returning %d", x.
name, ret);
287 int ipc_comm_recv(
const comm_t x,
char **data,
const size_t len,
288 const int allow_realloc) {
289 cislog_debug(
"ipc_comm_recv(%s)", x.
name);
295 ret = msgrcv(((
int*)x.
handle)[0], &t, CIS_MSG_MAX, 0, IPC_NOWAIT);
296 if (ret == -1 && errno == ENOMSG) {
297 cislog_debug(
"ipc_comm_recv(%s): no input, sleep", x.
name);
298 usleep(CIS_SLEEP_TIME);
300 cislog_debug(
"ipc_comm_recv(%s): received input: %d bytes, ret=%d",
301 x.
name, strlen(t.data), ret);
306 cislog_debug(
"ipc_comm_recv: msgrecv(%d, %p, %d, 0, IPC_NOWAIT): %s",
307 (
int*)x.
handle, &t, (
int)CIS_MSG_MAX, strerror(errno));
311 if (len_recv > (
int)len) {
313 cislog_debug(
"ipc_comm_recv(%s): reallocating buffer from %d to %d bytes.",
314 x.
name, (
int)len, len_recv);
315 (*data) = (
char*)realloc(*data, len_recv);
317 cislog_error(
"ipc_comm_recv(%s): failed to realloc buffer.", x.
name);
321 cislog_error(
"ipc_comm_recv(%s): buffer (%d bytes) is not large enough for message (%d bytes)",
322 x.
name, len, len_recv);
323 return -(len_recv - 1);
326 memcpy(*data, t.data, len_recv);
327 (*data)[len_recv - 1] =
'\0';
329 cislog_debug(
"ipc_comm_recv(%s): returns %d bytes", x.
name, ret);
345 int ipc_comm_send_nolimit(
const comm_t x,
const char *data,
const size_t len){
346 cislog_debug(
"ipc_comm_send_nolimit(%s): %d bytes", x.
name, len);
349 char msg[CIS_MSG_MAX];
350 sprintf(msg,
"%ld", (
long)(len));
351 ret = ipc_comm_send(x, msg, strlen(msg));
353 cislog_debug(
"ipc_comm_send_nolimit(%s): sending size of payload failed.", x.
name);
358 if ((len - prev) > CIS_MSG_MAX)
359 msgsiz = CIS_MSG_MAX;
362 ret = ipc_comm_send(x, data + prev, msgsiz);
364 cislog_debug(
"ipc_comm_send_nolimit(%s): send interupted at %d of %d bytes.",
365 x.
name, (
int)prev, (
int)len);
369 cislog_debug(
"ipc_comm_send_nolimit(%s): %d of %d bytes sent",
373 cislog_debug(
"ipc_comm_send_nolimit(%s): %d bytes completed", x.
name, len);
385 void ipc_install_error() {
386 cislog_error(
"Compiler flag 'IPCINSTALLED' not defined so IPC bindings are disabled.");
395 int free_ipc_comm(
comm_t *x) {
410 int new_ipc_address(
comm_t *comm) {
425 int init_ipc_comm(
comm_t *comm) {
440 int ipc_comm_nmsg(
const comm_t x) {
459 int ipc_comm_send(
const comm_t x,
const char *data,
const size_t len) {
483 int ipc_comm_recv(
const comm_t x,
char **data,
const size_t len,
484 const int allow_realloc) {
void * handle
Pointer to handle for comm.
Definition: CommBase.h:29
Communication structure.
Definition: CommBase.h:23
char address[COMM_ADDRESS_SIZE]
Comm address.
Definition: CommBase.h:26
char direction[COMM_DIR_SIZE]
send or recv for direction messages will go.
Definition: CommBase.h:27
char name[COMM_NAME_SIZE]
Comm name.
Definition: CommBase.h:25
int valid
1 if communicator initialized, 0 otherwise.
Definition: CommBase.h:28