/*************************************************************************** * * Name: bif_ipc_init * * Description: BIF IPC initialization routine. Will log into a instance * and access the bip output queues. * * * Input: none * Output: none * Returns: Success/Failure * ***************************************************************************/ int bif_ipc_init(Arb_connection *dbp) { int ret; /* Log into the instance */ ret = ipc_comm_init_qm(HOT_INVOICE_INSTANCE); if (ret < 0) { emit(BIFMOD, IPC_INST_LOG_FATAL, HOT_INVOICE_INSTANCE, ipc_error(ret)); return Failure; } /* Register bif message types */ ret = ipc_msg_type_register_simple(IPC_MSG_TYPE_BIP_BIF_OUTPUT, "BIP_BIF_OUTPUT_MSG"); if (ret < 0) { emit(BIFMOD, IPC_GEN_ERROR, "BIP-BIF Message type register", ipc_error(ret)); return Failure; } ret = ipc_msg_type_register_simple(IPC_MSG_TYPE_HOTINV_GUI_REPORT, "HOTINV_GUI_REPORT_MSG"); if (ret < 0) { emit(BIFMOD, IPC_GEN_ERROR, "BIF-GUI Message type register", ipc_error(ret)); return Failure; } /* Access the inupt data queue */ ret = ipc_msg_queue_create_public(dbp, HOTINVOICING_BIF_CAT, &Bif_data_queue); if (ret < 0) { emit(BIFMOD, IPC_Q_C_FATAL, arb_get_process_id(), ipc_error(ret)); return Failure; } return Success; }
/*************************************************************************** * * Name: bif_ipc_gui_report * * Description: BIF to GUI IPC result reporting routine. Will attempt to * access the GUI queue. If unable will return Failure. * If successful, it will then attempt again to access the queue, * and send the reply. * * Input: A string representing GUI input queue, and an error message. * Output: none * Returns: Success/Failure * ***************************************************************************/ int bif_ipc_gui_report(char *replyqname, HOTINV_GUI_REPORT_MSG *bif_gui_report) { int ret; Ipc_msg_qid Gui_queue; /* Access the GUI queue */ ret = ipc_msg_queue_access(&Gui_queue, replyqname, 0); if (ret < 0) { emit(BIFMOD, IPC_Q_A_WARNING, replyqname, ipc_error(ret)); return Failure; } // Front end application needs the original request-id (message-id) // to correctly identify its response... strcpy( bif_gui_report->gui_replqueue, replyqname ); /* Now send the message */ ret = ipc_msg_send_basic(bif_gui_report_msg_id, bif_gui_report, sizeof(HOTINV_GUI_REPORT_MSG), Gui_queue, 0, dbproc); if (ret < 0) { emit(BIFMOD, IPC_MSG_S_WARNING, "To GUI ", ipc_error(ret)); return Failure; } else { return Success; } }
void mapped_region::move(offset_t offset, std::size_t length, void *buffer) { if(buffer_ != 0) { close(); } int prots = 0; int flags = 0; switch(acmode_) { case ReadOnly: prots |= PROT_READ; flags |= MAP_SHARED; break; case ReadWrite: prots |= (PROT_WRITE | PROT_READ); flags |= MAP_SHARED; break; case CopyOnWrite: prots |= (PROT_WRITE | PROT_READ); flags |= MAP_PRIVATE; break; default: throw ipc_error("unknown mapping mode", 0); break; } // mapped region must be page aligned size_t page_size = get_page_size(); offset_t extra_offset= offset - (offset / page_size) * page_size; if(buffer) { buffer = static_cast<char* >(buffer) - extra_offset; } void* base = mmap(buffer, extra_offset + length, prots, flags, handle_, offset - extra_offset); if(base == MAP_FAILED) { int errcode = sys::err::get(); close(); throw ipc_error("mmap failed", errcode); } buffer_ = static_cast<char* >(base) + extra_offset; extoff_ = extra_offset; offset_ = offset; length_ = length; if(buffer && (base != buffer)) { close(); throw ipc_error("can't mapping to specified address", 0); } }
/*************************************************************************** * * Name: bip_ipc_send_bif * * Description: BIP to BIF IPC input routine. Will attempt to receive * a message from BIP telling BIP to process an invoice. * * * Input: none * Output: A message from BIF * Returns: Success/Failure * ***************************************************************************/ int bif_ipc_get_bip_invoice(BIP_BIF_OUTPUT_MSG *bip_bif_input) { int ret; // Message-id field (bill_replqueue) is used to filter messages to dequeue, // No filtering required here - get next available message... strcpy( bip_bif_input->bill_replqueue, "" ); // After ipc_msg_receive call, bip_gui_input->bill_replqueue will contain // the message-id of the hotbill request... ret = ipc_msg_receive(&bip_bif_output_msg_id, bip_bif_input, sizeof(BIP_GUI_INPUT_MSG), NULL, 0, 0, Bif_data_queue, IPC_MSG_FIRST, NULL, NULL, NULL, 0, HOT_INVOICE_TIMEOUT, dbproc); if (ret < 0) { if (ret == IPC_MSG_TIMEOUT) { bip_bif_input->bill_ref_no = -1; } emit(BIFMOD, IPC_MSG_R_WARNING, "From BIP ", ipc_error(ret)); return Success; } else { return Success; } }
void queue_create( Ipc_msg_qid *queueA) { int ret = 0; ret = ipc_msg_queue_create(queueA, "queA", 0); if (ret < 0) { printf("ipc_msg_queue_create returns %s\n", ipc_error(ret)); } else { printf("ipc_msg_queue_create: Got ret %d q %d\n", ret, *queueA); } ret = ipc_msg_queue_access(queueA, "queA", 0); if (ret < 0) { printf("ipc_msg_queue_access returns %s\n", ipc_error(ret)); } else { printf("ipc_msg_queue_access: Got queue %d\n", *queueA); } }
void test_generic_message( Ipc_msg_qid queueA, Ipc_msg_flag fastpath) { int msgs, ret; char buf[2048]; time_t now; char clocktime[10]; printf("test_generic_message: Starting\n"); strcpy(buf, "Generic Test"); now = time( NULL ); strftime( clocktime, 9, "%H:%M:%S", localtime( &now ) ); printf("Started DiskBased (MomSys) %d txns: %s\n", loop_normal, clocktime); for (ret=0, msgs=0; msgs < loop_normal; msgs++) { ret = ipc_msg_send_generic(buf, strlen(buf), queueA, fastpath); if ( ret < 0 ) break; } now = time( NULL ); strftime( clocktime, 9, "%H:%M:%S", localtime( &now ) ); printf("Ended DiskBased (MomSys) %d txns: %s\n", msgs, clocktime); if (ret < 0) { printf("ipc_msg_send_generic returns %s\n", ipc_error(ret)); } else { printf("ipc_msg_send_generic: Send ret %d buf %s\n", ret, buf); } ret = ipc_msg_receive_generic(buf, 256, queueA, 0); if (ret < 0) { printf("ipc_msg_receive_generic returns %s\n", ipc_error(ret)); } else { printf("ipc_msg_receive_generic: Recv ret %d buf %s\n", ret, buf); } printf("test_generic_message: Finishing\n"); }
void queue_destroy( Ipc_msg_qid queueA) { int ret; ret = ipc_msg_queue_delete(queueA, IPC_MSG_QUEUE_DESTROY); if (ret < 0) { printf("ipc_msg_queue_delete returns %s\n", ipc_error(ret)); } else { printf("ipc_msg_queue_delete: Got ret %d\n", ret); } }
void ipc_init() { int ret; ret = ipc_comm_init(instance_name); if (ret < 0) { printf("ipc_comm_init returns %s\n", ipc_error(ret)); } else { printf("ipc_comm_init: Got ret %d\n", ret); } }
/*************************************************************************** * * Name: bif_ipc_shutdown * * Description: BIF IPC shutdown routine. Will log out of the instance. * * * Input: none * Output: none * Returns: Success/Failure * ***************************************************************************/ int bif_ipc_shutdown() { int ret; /* Log out of the instance */ ret = ipc_comm_shutdown(); if (ret < 0) { emit(BIFMOD, IPC_INST_LOGO_WARN, HOT_INVOICE_INSTANCE, ipc_error(ret)); return Failure; } return Success; }
int send_msg(BIP_GUI_INPUT_MSG *msg) { int ret; ret = ipc_msg_send_basic(IPC_MSG_TYPE_BIP_GUI_INPUT, msg, sizeof(BIP_GUI_INPUT_MSG), Bip_data_queue, 0); if (ret < 0) { printf("send_msg: erorr %s\n", ipc_error(ret)); } else { printf("send_msg: Success\n"); } return ret; }
mapped_region::mapped_region(const memory_mappable &mappable, accessmode_t mode, offset_t offset, std::size_t length, void *buffer) : handle_(mappable.handle()), buffer_(NULL), offset_(0), length_(0), extoff_(0), acmode_(mode) { if(length == 0) { offset_t total_size = mappable.size(); if(total_size <= offset) { throw ipc_error("mapped region out of range", 0); } length = total_size - offset; } move(offset, length, buffer); }
recv_msg(HOTINV_GUI_REPORT_MSG *msg) { int ret; Ipc_msg_type_id hotinv_id = IPC_MSG_TYPE_HOTINV_GUI_REPORT; ret = ipc_msg_receive(&hotinv_id, msg, sizeof(HOTINV_GUI_REPORT_MSG), NULL, 0, 0, ReplyId, IPC_MSG_FIRST, NULL, NULL, NULL, 0, BIP_IPC_MSG_TIMEOUT); if (ret < 0) { printf("recv_msg: erorr %s\n", ipc_error(ret)); } else { printf("recv_msg: Success\n"); printf("\ngui_key=%d, gui_data=%d, gui_status=%d, gui_ref_no=%d, gui_ref_resets=%d", msg->gui_key, msg->gui_data, msg->gui_status,msg->gui_ref_no, msg->gui_ref_resets); } return ret; }
main( int argc, char *argv[]) { int ret; char bipname[256]; int account_no = 16002; char hostname[256]; char *argbuf; if (argc != 2) { usage(); } argbuf = argv[1]; for (argbuf = argv[1]; *argbuf != NULL; argbuf++) { printf("argbuf is %c\n", *argbuf); if (!isdigit(*argbuf)) { usage(); } } account_no = atoi(argv[1]); printf("Processing account %d\n", account_no ); ret = ipc_comm_init(Bip_instname); if (ret < 0) { printf("Unable to init inst error %s\n", ipc_error(ret)); return 0; } #ifdef DATABASE /* * If we have a database, then we will lookup the list of output queues * using ipc_msg_queue_find. This routine takes an array of 10 names * and will fill 1 or more entries. If no entries can be filled, an error * is returned. */ { Ipc_msg_queue_array bip_output_queues; Arb_connection *dbp; int j; int array_size; /* NULL out the message queue name buffer */ array_size = sizeof(bip_output_queues)/sizeof(bip_output_queues[0]); for (j = 0; j < array_size; j++) { bip_output_queues[j][0] = '\0'; } /* Access the output data queue */ if (ipc_msg_queue_find(dbp, HOTINVOICING_BIP_CAT, bip_output_queues) != Success) { goto cleanup; } /* We only expect one queue, so just take that one */ strcpy(bipname, bip_output_queues[0]); } #else /* DATABASE */ sprintf(bipname, "@mila52d1:%s:bip01", &Bip_instname[1]); #endif /* DATABASE */ printf("About to access BIP queue %s\n", bipname); ret = ipc_msg_queue_access(&Bip_data_queue, bipname, 0); if (ret < 0) { printf("Unable to access queue %s error %s\n", bipname, ipc_error(ret)); goto cleanup; } printf("About to register message types\n"); /* Register bip input message */ ret = ipc_msg_type_register_simple(IPC_MSG_TYPE_BIP_GUI_INPUT, "BIP_GUI_INPUT_MSG"); if (ret < 0) { printf("Unable to register messagetype error %s\n", ipc_error(ret)); goto cleanup; } /* Register GUI report message */ ret = ipc_msg_type_register_simple(IPC_MSG_TYPE_HOTINV_GUI_REPORT, "HOTINV_GUI_REPORT_MSG"); if (ret < 0) { printf("Unable to register messagetype error %s\n", ipc_error(ret)); goto cleanup; } ret = gethostname(hostname, sizeof(hostname)); if (ret != 0) { return Failure; } /* * NOTE: Make sure to use the short name in rely queue creation. * i.e. use "gui01" to create or access when we know the queue * is local. When it is remote, we will use the full path name. * Using the full path to create the local queue will break * the naming convention. * * Also note that in creating the full path, we skip the @ before * the instance name, so we create the correct string: * "@bishop:HotInvoice:gui01" instead of the wrong string * "@bishop:@HotInvoice:gui01". */ sprintf(Gui_reply_queue_full_name, "@%s:%s:%s", hostname, &Bip_instname[1], Gui_reply_queue_name); /* Create the reply queue, if there is one already, then access it */ ret = ipc_msg_queue_create(&ReplyId, Gui_reply_queue_name, 0); if (ret < 0) { printf("Unable to create reply Q error %s try access\n", ipc_error(ret)); ret = ipc_msg_queue_access(&ReplyId, Gui_reply_queue_name, 0); if (ret < 0) { printf("Unable to access reply Q %s error %s\n", Gui_reply_queue_name, ipc_error(ret)); goto cleanup; } } /* Now make a message */ { BIP_GUI_INPUT_MSG omsg; HOTINV_GUI_REPORT_MSG imsg; printf("Posting a request for account %d\n", account_no); (void) make_msg(account_no, &omsg); if (send_msg(&omsg) < 0) { goto cleanup; } if (recv_msg(&imsg) < 0) { goto cleanup; } printf("Got reply for account %d received status %d\n", account_no, imsg.gui_status); } cleanup: ipc_comm_shutdown(); return 0; }