2 #include <../serialize/serialize.h> 3 #include <comm_header.h> 8 #include <ServerComm.h> 9 #include <ClientComm.h> 10 #include <AsciiFileComm.h> 11 #include <AsciiTableComm.h> 12 #include <DefaultComm.h> 15 #ifndef CISCOMMUNICATION_H_ 16 #define CISCOMMUNICATION_H_ 19 static void **vcomms2clean = NULL;
20 static size_t ncomms2clean = 0;
21 static size_t clean_registered = 0;
25 int comm_send_eof(
const comm_t x);
27 int comm_nmsg(
const comm_t x);
36 int free_comm_type(
comm_t *x) {
37 comm_type t = x->
type;
40 ret = free_ipc_comm(x);
41 else if (t == ZMQ_COMM)
42 ret = free_zmq_comm(x);
43 else if (t == RPC_COMM)
44 ret = free_rpc_comm(x);
45 else if (t == SERVER_COMM)
46 ret = free_server_comm(x);
47 else if (t == CLIENT_COMM)
48 ret = free_client_comm(x);
49 else if (t == ASCII_FILE_COMM)
50 ret = free_ascii_file_comm(x);
51 else if ((t == ASCII_TABLE_COMM) || (t == ASCII_TABLE_ARRAY_COMM))
52 ret = free_ascii_table_comm(x);
54 cislog_error(
"free_comm_type: Unsupported comm_type %d", t);
69 comm_type t = x->
type;
72 if (_cis_error_flag == 0) {
74 while (comm_nmsg(*x) > 0) {
75 cislog_debug(
"free_comm(%s): draining %d messages",
76 x->
name, comm_nmsg(*x));
77 usleep(CIS_SLEEP_TIME);
80 cislog_error(
"free_comm(%s): Error registered", x->
name);
83 ret = free_comm_type(x);
87 if (vcomms2clean[idx] != NULL) {
88 free(vcomms2clean[idx]);
89 vcomms2clean[idx] = NULL;
99 void clean_comms(
void) {
101 for (i = 0; i < ncomms2clean; i++) {
102 if (vcomms2clean[i] != NULL) {
103 free_comm((
comm_t*)(vcomms2clean[i]));
106 if (vcomms2clean != NULL) {
111 #if defined(ZMQINSTALLED) 115 cislog_debug(
"atexit done");
126 int register_comm(
comm_t *x) {
127 if (clean_registered == 0) {
129 clean_registered = 1;
134 void **t_vcomms2clean = (
void**)realloc(vcomms2clean,
sizeof(
void*)*(ncomms2clean + 1));
135 if (t_vcomms2clean == NULL) {
136 cislog_error(
"register_comm(%s): Failed to realloc the comm list.", x->
name);
139 vcomms2clean = t_vcomms2clean;
141 vcomms2clean[ncomms2clean++] = (
void*)x;
152 int new_comm_type(
comm_t *x) {
153 comm_type t = x->
type;
156 flag = new_ipc_address(x);
157 else if (t == ZMQ_COMM)
158 flag = new_zmq_address(x);
159 else if (t == RPC_COMM)
160 flag = new_rpc_address(x);
161 else if (t == SERVER_COMM)
162 flag = new_server_address(x);
163 else if (t == CLIENT_COMM)
164 flag = new_client_address(x);
165 else if (t == ASCII_FILE_COMM)
166 flag = new_ascii_file_address(x);
167 else if (t == ASCII_TABLE_COMM)
168 flag = new_ascii_table_address(x);
169 else if (t == ASCII_TABLE_ARRAY_COMM)
170 flag = new_ascii_table_array_address(x);
172 cislog_error(
"new_comm_type: Unsupported comm_type %d", t);
185 int init_comm_type(
comm_t *x) {
186 comm_type t = x->
type;
189 flag = init_ipc_comm(x);
190 else if (t == ZMQ_COMM)
191 flag = init_zmq_comm(x);
192 else if (t == RPC_COMM)
193 flag = init_rpc_comm(x);
194 else if (t == SERVER_COMM)
195 flag = init_server_comm(x);
196 else if (t == CLIENT_COMM)
197 flag = init_client_comm(x);
198 else if (t == ASCII_FILE_COMM)
199 flag = init_ascii_file_comm(x);
200 else if (t == ASCII_TABLE_COMM)
201 flag = init_ascii_table_comm(x);
202 else if (t == ASCII_TABLE_ARRAY_COMM)
203 flag = init_ascii_table_array_comm(x);
205 cislog_error(
"init_comm_type: Unsupported comm_type %d", t);
208 cislog_debug(
"init_comm_type(%s): Done, flag = %d", x->
name, flag);
223 comm_t new_comm(
char *address,
const char *direction,
const comm_type t,
225 comm_t *ret = new_comm_base(address, direction, t, seri_info);
227 cislog_error(
"new_comm: Could not initialize base.");
228 return empty_comm_base();
231 if (address == NULL) {
232 flag = new_comm_type(ret);
234 flag = init_comm_type(ret);
237 cislog_error(
"new_comm: Failed to initialize new comm address.");
240 if (strlen(ret->name) == 0) {
241 sprintf(ret->name,
"temp.%s", ret->address);
243 flag = register_comm(ret);
245 cislog_error(
"new_comm: Failed to register new comm.");
265 comm_t init_comm(
const char *name,
const char *direction,
const comm_type t,
266 const void *seri_info) {
267 cislog_debug(
"init_comm: Initializing comm.");
269 SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX);
270 _set_abort_behavior(0,_WRITE_ABORT_MSG);
272 comm_t *ret = init_comm_base(name, direction, t, seri_info);
274 cislog_error(
"init_comm(%s): Could not initialize base.", name);
275 return empty_comm_base();
277 int flag = init_comm_type(ret);
279 cislog_error(
"init_comm(%s): Could not initialize comm.", name);
282 flag = register_comm(ret);
284 cislog_error(
"init_comm(%s): Failed to register new comm.", name);
288 cislog_debug(
"init_comm(%s): Initialized comm.", name);
298 int comm_nmsg(
const comm_t x) {
301 cislog_error(
"comm_nmsg: Invalid comm");
304 comm_type t = x.
type;
306 ret = ipc_comm_nmsg(x);
307 else if (t == ZMQ_COMM)
308 ret = zmq_comm_nmsg(x);
309 else if (t == RPC_COMM)
310 ret = rpc_comm_nmsg(x);
311 else if (t == SERVER_COMM)
312 ret = server_comm_nmsg(x);
313 else if (t == CLIENT_COMM)
314 ret = client_comm_nmsg(x);
315 else if (t == ASCII_FILE_COMM)
316 ret = ascii_file_comm_nmsg(x);
317 else if ((t == ASCII_TABLE_COMM) || (t == ASCII_TABLE_ARRAY_COMM))
318 ret = ascii_table_comm_nmsg(x);
320 cislog_error(
"comm_nmsg: Unsupported comm_type %d", t);
335 int comm_send_single(
const comm_t x,
const char *data,
const size_t len) {
338 cislog_error(
"comm_send_single: Invalid comm");
341 comm_type t = x.
type;
343 ret = ipc_comm_send(x, data, len);
344 else if (t == ZMQ_COMM)
345 ret = zmq_comm_send(x, data, len);
346 else if (t == RPC_COMM)
347 ret = rpc_comm_send(x, data, len);
348 else if (t == SERVER_COMM)
349 ret = server_comm_send(x, data, len);
350 else if (t == CLIENT_COMM)
351 ret = client_comm_send(x, data, len);
352 else if (t == ASCII_FILE_COMM)
353 ret = ascii_file_comm_send(x, data, len);
354 else if ((t == ASCII_TABLE_COMM) || (t == ASCII_TABLE_ARRAY_COMM))
355 ret = ascii_table_comm_send(x, data, len);
357 cislog_error(
"comm_send_single: Unsupported comm_type %d", t);
379 sprintf(head.
id,
"%d", rand());
385 if (x.
type == CLIENT_COMM) {
391 if (serializer->
type == DIRECT_SERI) {
393 }
else if (serializer->
type == FORMAT_SERI) {
396 }
else if (serializer->
type == ARRAY_SERI) {
400 }
else if (serializer->
type == ASCII_TABLE_SERI) {
404 }
else if (serializer->
type == ASCII_TABLE_ARRAY_SERI) {
412 if (x.
type == SERVER_COMM)
414 else if (x.
type == CLIENT_COMM)
415 head = client_response_header(x, head);
427 int comm_send_multipart(
const comm_t x,
const char *data,
const size_t len) {
429 int headbuf_len = CIS_MSG_BUF;
430 int headlen = 0, ret = -1;
432 cislog_error(
"comm_send_multipart: Invalid comm");
435 comm_t xmulti = empty_comm_base();
437 comm_head_t head = comm_send_multipart_header(x, len);
438 if (head.
valid == 0) {
439 cislog_error(
"comm_send_multipart: Invalid header generated.");
442 char *headbuf = (
char*)malloc(headbuf_len);
443 if (headbuf == NULL) {
444 cislog_error(
"comm_send_multipart: Failed to malloc headbuf.");
449 headlen = format_comm_header(head, headbuf, headbuf_len);
451 cislog_error(
"comm_send_multipart: Failed to format header.");
456 if (((
size_t)headlen + len + 1) > (
size_t)headbuf_len) {
457 char *t_headbuf = (
char*)realloc(headbuf, (
size_t)headlen + len + 1);
458 if (t_headbuf == NULL) {
459 cislog_error(
"comm_send_multipart: Failed to realloc headbuf.");
464 headbuf_len = headlen + (int)len + 1;
467 memcpy(headbuf + headlen, data, len);
469 headbuf[headlen] =
'\0';
475 xmulti = new_comm(NULL,
"send", x.
type, NULL);
476 if (!(xmulti.
valid)) {
477 cislog_error(
"comm_send_multipart: Failed to initialize a new comm.");
484 headlen = format_comm_header(head, headbuf, headbuf_len);
486 cislog_error(
"comm_send_multipart: Failed to format header.");
493 ret = comm_send_single(x, headbuf, headlen);
495 cislog_error(
"comm_send_multipart: Failed to send header.");
502 cislog_debug(
"comm_send_multipart(%s): %d bytes completed", x.
name, head.
size);
509 while (prev < head.
size) {
513 msgsiz = head.
size - prev;
514 ret = comm_send_single(xmulti, data + prev, msgsiz);
516 cislog_debug(
"comm_send_multipart(%s): send interupted at %d of %d bytes.",
521 cislog_debug(
"comm_send_multipart(%s): %d of %d bytes sent",
525 cislog_debug(
"comm_send_multipart(%s): %d bytes completed", x.
name, head.
size);
545 int comm_send(
const comm_t x,
const char *data,
const size_t len) {
548 cislog_error(
"comm_send: Invalid comm");
552 cislog_error(
"comm_send(%s): sent_eof not initialized.", x.
name);
561 cislog_error(
"comm_send(%s): EOF already sent", x.
name);
567 return comm_send_multipart(x, data, len);
569 ret = comm_send_single(x, data, len);
571 cislog_debug(
"comm_send(%s): sent EOF, ret = %d", x.
name, ret);
584 int comm_send_eof(
const comm_t x) {
586 char buf[100] = CIS_MSG_EOF;
587 ret = comm_send(x, buf, strlen(buf));
604 int comm_recv_single(
const comm_t x,
char **data,
const size_t len,
605 const int allow_realloc) {
608 cislog_error(
"comm_recv_single: Invalid comm");
611 comm_type t = x.
type;
613 ret = ipc_comm_recv(x, data, len, allow_realloc);
614 else if (t == ZMQ_COMM)
615 ret = zmq_comm_recv(x, data, len, allow_realloc);
616 else if (t == RPC_COMM)
617 ret = rpc_comm_recv(x, data, len, allow_realloc);
618 else if (t == SERVER_COMM)
619 ret = server_comm_recv(x, data, len, allow_realloc);
620 else if (t == CLIENT_COMM)
621 ret = client_comm_recv(x, data, len, allow_realloc);
622 else if (t == ASCII_FILE_COMM)
623 ret = ascii_file_comm_recv(x, data, len, allow_realloc);
624 else if ((t == ASCII_TABLE_COMM) || (t == ASCII_TABLE_ARRAY_COMM))
625 ret = ascii_table_comm_recv(x, data, len, allow_realloc);
627 cislog_error(
"comm_recv: Unsupported comm_type %d", t);
643 int comm_recv_multipart(
const comm_t x,
char **data,
const size_t len,
644 const size_t headlen,
const int allow_realloc) {
647 cislog_error(
"comm_recv_multipart: Invalid comm");
651 comm_head_t head = parse_comm_header(*data, headlen);
653 cislog_error(
"comm_recv(%s): Error parsing header.", x.
name);
660 cislog_debug(
"comm_recv(%s): Updating serializer type to %d",
663 new_type = DIRECT_SERI;
665 new_type = FORMAT_SERI;
667 new_type = ASCII_TABLE_ARRAY_SERI;
672 new_type = ASCII_TABLE_SERI;
674 new_type = ASCII_TABLE_ARRAY_SERI;
678 ret = update_serializer(x.
serializer, new_type, new_info);
680 cislog_error(
"comm_recv(%s): Error updating serializer.", x.
name);
685 if ((new_type == ASCII_TABLE_SERI) || (new_type == ASCII_TABLE_ARRAY_SERI)) {
687 ret = at_update(table, x.
name,
"0");
689 cislog_error(
"comm_recv(%s): Failed to update asciiTable address.",
693 ret = simplify_formats(table->
format_str, CIS_MSG_MAX);
695 cislog_error(
"comm_recv(%s): Failed to simplify recvd table format.", x.
name);
698 }
else if (new_type == FORMAT_SERI) {
702 cislog_error(
"comm_recv(%s): Failed to simplify recvd format.", x.
name);
718 if (!(xmulti.
valid)) {
719 cislog_error(
"comm_recv_multipart: Failed to initialize a new comm.");
728 if ((head.
size + 1) > len) {
730 char *t_data = (
char*)realloc(*data, head.
size + 1);
731 if (t_data == NULL) {
732 cislog_error(
"comm_recv_multipart(%s): Failed to realloc buffer",
740 cislog_error(
"comm_recv_multipart(%s): buffer is not large enough",
747 char *pos = (*data) + prev;
748 while (prev < head.
size) {
752 msgsiz = head.
size - prev + 1;
753 ret = comm_recv_single(xmulti, &pos, msgsiz, 0);
755 cislog_debug(
"comm_recv_multipart(%s): recv interupted at %d of %d bytes.",
761 cislog_debug(
"comm_recv_multipart(%s): %d of %d bytes received",
765 cislog_debug(
"comm_recv_multipart(%s): %d bytes completed", x.
name, prev);
789 int comm_recv(
const comm_t x,
char *data,
const size_t len) {
790 int ret = comm_recv_single(x, &data, len, 0);
793 cislog_debug(
"comm_recv(%s): EOF received.", x.
name);
797 ret = comm_recv_multipart(x, &data, len, ret, 0);
800 cislog_error(
"comm_recv_realloc(%s): Failed to receive header or message.",
816 int comm_recv_realloc(
const comm_t x,
char **data,
const size_t len) {
817 int ret = comm_recv_single(x, data, len, 1);
820 cislog_debug(
"comm_recv_realloc(%s): EOF received.", x.
name);
824 ret = comm_recv_multipart(x, data, len, ret, 1);
827 cislog_error(
"comm_recv_realloc(%s): Failed to receive header or message.",
836 int comm_send_nolimit(
const comm_t x,
const char *data,
const size_t len) {
837 return comm_send(x, data, len);
846 int comm_send_nolimit_eof(
const comm_t x) {
849 cislog_error(
"comm_send_nolimit_eof: Invalid comm");
853 cislog_error(
"comm_send_nolimit_eof(%s): sent_eof not initialized.", x.
name);
857 char buf[2048] = CIS_MSG_EOF;
858 ret = comm_send_nolimit(x, buf, strlen(buf));
861 cislog_error(
"comm_send_nolimit_eof(%s): EOF already sent", x.
name);
880 int comm_recv_nolimit(
const comm_t x,
char **data,
const size_t len) {
881 return comm_recv_realloc(x, data, len);
895 int vcommSend(
const comm_t x, va_list ap) {
898 cislog_error(
"vcommSend: Invalid comm");
901 size_t buf_siz = CIS_MSG_BUF;
903 char *buf = (
char*)malloc(buf_siz);
905 cislog_error(
"vcommSend(%s): Failed to alloc buffer", x.
name);
909 if (x.
type == CLIENT_COMM) {
914 ret = serialize(*serializer, &buf, buf_siz, 1, &args_used, ap);
916 cislog_error(
"vcommSend(%s): serialization error", x.
name);
920 ret = comm_send(x, buf, ret);
921 cislog_debug(
"vcommSend(%s): comm_send returns %d", x.
name, ret);
943 int vcommRecv(
const comm_t x, va_list ap) {
946 cislog_error(
"vcommRecv: Invalid comm");
950 size_t buf_siz = CIS_MSG_BUF;
952 char *buf = (
char*)malloc(buf_siz);
954 cislog_error(
"vcommSend(%s): Failed to alloc buffer", x.
name);
957 ret = comm_recv_nolimit(x, &buf, buf_siz);
963 cislog_debug(
"vcommRecv(%s): comm_recv returns %d: %.10s...", x.
name, ret, buf);
966 if (x.
type == SERVER_COMM) {
970 ret = deserialize(*serializer, buf, ret, ap);
972 cislog_error(
"vcommRecv(%s): error deserializing message (ret=%d)",
977 cislog_debug(
"vcommRecv(%s): deserialize_format returns %d", x.
name, ret);
982 #define vcommSend_nolimit vcommSend 983 #define vcommRecv_nolimit vcommRecv void * handle
Pointer to handle for comm.
Definition: CommBase.h:25
char format_str[LINE_SIZE_MAX]
Format string for rows.
Definition: AsciiTable.h:78
Communication structure.
Definition: CommBase.h:19
char address[COMM_ADDRESS_SIZE]
Comm address.
Definition: CommBase.h:22
Serializer structure.
Definition: SerializeBase.h:15
time_t * last_send
Clock output at time of last send.
Definition: CommBase.h:31
void * info
Pointer to any extra info serializer requires.
Definition: SerializeBase.h:17
int multipart
1 if message is multipart, 0 if it is not.
Definition: comm_header.h:18
size_t bodybeg
Start of body in header.
Definition: comm_header.h:20
size_t maxMsgSize
The maximum message size.
Definition: CommBase.h:28
size_t size_info
Size of allocate space for info.
Definition: SerializeBase.h:18
int * used
Flag specifying if the comm has been used.
Definition: CommBase.h:34
char address[COMMBUFFSIZ]
Address that message will comm in on.
Definition: comm_header.h:17
comm_type type
Comm type.
Definition: CommBase.h:20
int valid
1 if the header is valid, 0 otherwise.
Definition: comm_header.h:21
int is_file
Flag specifying if the comm connects directly to a file.
Definition: CommBase.h:36
int always_send_header
1 if comm should always send a header.
Definition: CommBase.h:29
seri_t * serializer
Serializer for comm messages.
Definition: CommBase.h:27
char format_str[COMMBUFFSIZ]
Format string for serializer.
Definition: comm_header.h:26
size_t bodysiz
Size of body.
Definition: comm_header.h:19
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 * sent_eof
Flag specifying if EOF has been sent.
Definition: CommBase.h:32
size_t size
Size of incoming message.
Definition: comm_header.h:16
int valid
1 if communicator initialized, 0 otherwise.
Definition: CommBase.h:24
int * recv_eof
Flag specifying if EOF has been received.
Definition: CommBase.h:33
int as_array
1 if messages will be serialized arrays.
Definition: comm_header.h:29
int serializer_type
Code indicating the type of serializer.
Definition: comm_header.h:25
Structure containing information about an ASCII table.
Definition: AsciiTable.h:76
char id[COMMBUFFSIZ]
Unique ID associated with this message.
Definition: comm_header.h:22
int index_in_register
Index of the comm in the comm register.
Definition: CommBase.h:30
seri_type type
Serializer type.
Definition: SerializeBase.h:16
Header information passed by comms for multipart messages.
Definition: comm_header.h:15