📄 nml.cc
字号:
* be an NML_SERVER, which effects how and when messages are encoded and* decoded.* int set_to_master - Passed to the CMS constructor - how this is used* depends on the type of CMS buffer. In general the master is responsible* for creating/initializing the buffer. If set_to_master == 1 then this* process will be considered the master, if set_to_master == 0 then* the the configuration file determines if this is the master, and it* set_to_master == -1 then this will not be the master.* NOTES:* 1. Borland C++(for DOS and Windows) does not allow default* parameters to be specified both here and in the header file.* 2. All pointers are first initialized to NULL so that it can be determined* later if the constructor returned before creating the objects* the pointers are intended to point at.* 3. This constructor does not register itself with the default server.* 4. The NML object created by this constructor can not be used until* the format_chain is constructed. (This may be done by* derived classes. )******************************************************************/NML::NML(char *buffer_line, char *proc_line){ registered_with_server = 0; cms_for_msg_string_conversions = 0; cms = (CMS *) NULL; blocking_read_poll_interval = -1.0; forced_type = 0; info_printed = 0; already_deleted = 0; format_chain = (LinkedList *) NULL; phantom_read = (NMLTYPE(*)())NULL; phantom_peek = (NMLTYPE(*)())NULL; phantom_write = (int (*)(NMLmsg *)) NULL; phantom_write_if_read = (int (*)(NMLmsg *)) NULL; phantom_check_if_read = (int (*)()) NULL; phantom_clear = (int (*)()) NULL; channel_list_id = 0; error_type = NML_NO_ERROR; ignore_format_chain = 0; fast_mode = 0; channel_type = NML_GENERIC_CHANNEL_TYPE; if (-1 == cms_create_from_lines(&cms, buffer_line, proc_line)) { if (verbose_nml_error_messages) { rcs_print_error("NML: cms_create_from_lines returned -1.\n"); } if (!info_printed) { print_info(); } if (NULL != cms) { rcs_print_debug(PRINT_NML_DESTRUCTORS, " delete (CMS *) %X;\n", cms); delete cms; cms = (CMS *) NULL; } error_type = NML_INVALID_CONFIGURATION; return; } if (NULL == cms) { error_type = NML_INVALID_CONFIGURATION; return; } if (cms->status < 0) { error_type = NML_INVALID_CONFIGURATION; if (verbose_nml_error_messages) { rcs_print_error("NML: cms->status = %d.\n", cms->status); } if (!info_printed) { print_info(); } rcs_print_debug(PRINT_NML_DESTRUCTORS, " delete (CMS *) %X;\n", cms); delete cms; cms = (CMS *) NULL; return; } add_to_channel_list(); if (!cms->is_phantom && cms->ProcessType == CMS_LOCAL_TYPE && !cms->neutral && !cms->isserver) { fast_mode = 1; } cms_status = (int *) &(cms->status); cms_inbuffer_header_size = &(cms->header.in_buffer_size); if (NULL != cms) { char *forced_type_eq = strstr(cms->buflineupper, "FORCE_TYPE="); if (forced_type_eq != NULL) { long temp = 0; temp = strtol(forced_type_eq + 11, NULL, 0); if (temp > 0) { forced_type = temp; fast_mode = 0; } } char *brpi_eq = strstr(cms->buflineupper, "BRPI="); if (brpi_eq != NULL) { blocking_read_poll_interval = strtod(brpi_eq + 5, NULL); } register_with_server(); }}/**************************************************************** NML Member Function: add_to_channel_list()* Purpose:* Adds a pointer to this NML object to the main NML list.* The list is used by nml_cleanup to delete all NML objects owned by* a process.* Under VxWorks the list must be shared by all processes so we must* remember which process (also known as a task) added it to the list.* (This is a great reason for tossing VxWorks in the circular file!)*****************************************************************/void NML::add_to_channel_list(){ if (NULL == NML_Main_Channel_List) { NML_Main_Channel_List = new LinkedList; } if (NULL != NML_Main_Channel_List) { channel_list_id = NML_Main_Channel_List->store_at_tail(this, sizeof(NML), 0); }}/********************************************************************* NML Member Function: register_with_server()* Purpose:* The NML_Default_Super_Server keeps a list of all of the NML objects* that were specified as servers in the config file.* When nml_start is called servers will be spawned for these buffers.* The NML_Default_Super_Server also tries to reduce the number of processes* spawned by grouping buffers with the same buffer number.********************************************************************/void NML::register_with_server(){ if (NULL != cms && !registered_with_server) { if (cms->spawn_server) { if (NULL == NML_Default_Super_Server) { NML_Default_Super_Server = new NML_SUPER_SERVER; } NML_Default_Super_Server->add_to_list(this); registered_with_server = 1; } }}/*************************************************************** NML Constructor:* Parameters:* NML *nml; - pointer to NML object to duplicate.* int set_to_server - If 1 this NML will consider its calling process to* be an NML_SERVER, which effects how and when messages are encoded and* decoded.* int set_to_master - Passed to the CMS constructor - how this is used* depends on the type of CMS buffer. In general the master is responsible* for creating/initializing the buffer. If set_to_master == 1 then this* process will be considered the master, if set_to_master == 0 then* the the configuration file determines if this is the master, and it* set_to_master == -1 then this will not be the master.* NOTES:* 1. Borland C++(for DOS and Windows) does not allow default* parameters to be specified both here and in the header file.* 2. All pointers are first initialized to NULL so that it can be determined* later if the constructor returned before creating the objects* the pointers are intended to point at.*************************************************************/NML::NML(NML * nml_ptr, int set_to_server, int set_to_master){ registered_with_server = 0; cms_for_msg_string_conversions = 0; already_deleted = 0; forced_type = 0; cms = (CMS *) NULL; format_chain = (LinkedList *) NULL; error_type = NML_NO_ERROR; ignore_format_chain = 0; channel_list_id = 0; fast_mode = 0; info_printed = 0; blocking_read_poll_interval = -1.0; channel_type = NML_GENERIC_CHANNEL_TYPE; if (NULL != nml_ptr) { strncpy(bufname, nml_ptr->bufname, 40); strncpy(procname, nml_ptr->procname, 40); strncpy(cfgfilename, nml_ptr->cfgfilename, 160); if (NULL != nml_ptr->cms) { // Create a CMS channel identitical to the one from the argument // NML channel accept that the channel may be set_to_server or // set_to_master differently. cms_copy(&cms, nml_ptr->cms, set_to_server, set_to_master); if (NULL != cms) { cms->current_subdivision = nml_ptr->cms->current_subdivision; } } } if (!ignore_format_chain) { format_chain = new LinkedList; if ((NULL != nml_ptr->format_chain) && (NULL != format_chain)) { LinkedList *from, *to; NML_FORMAT_PTR format_func_ptr; from = nml_ptr->format_chain; to = format_chain; format_func_ptr = (NML_FORMAT_PTR) from->get_head(); while (NULL != format_func_ptr) { to->store_at_tail((void *) format_func_ptr, 0, 0); format_func_ptr = (NML_FORMAT_PTR) from->get_next(); } } } if (NULL == cms) { return; } add_to_channel_list(); if (!cms->is_phantom && cms->ProcessType == CMS_LOCAL_TYPE && !cms->neutral && !cms->isserver) { fast_mode = 1; } cms_status = (int *) &(cms->status); cms_inbuffer_header_size = &(cms->header.in_buffer_size); char *forced_type_eq = strstr(cms->buflineupper, "FORCE_TYPE="); if (forced_type_eq != NULL) { long temp = 0; temp = strtol(forced_type_eq + 11, NULL, 0); if (temp > 0) { forced_type = temp; fast_mode = 0; } } char *brpi_eq = strstr(cms->buflineupper, "BRPI="); if (brpi_eq != NULL) { blocking_read_poll_interval = strtod(brpi_eq + 5, NULL); } if (NULL != nml_ptr->cms->dpi) { CMS_DIAG_PROC_INFO *dpi = cms->get_diag_proc_info(); *dpi = *(nml_ptr->cms->get_diag_proc_info()); cms->set_diag_proc_info(dpi); } cms->first_diag_store = nml_ptr->cms->first_diag_store; if (NULL != cms->handle_to_global_data && NULL != nml_ptr->cms->handle_to_global_data) { cms->handle_to_global_data->total_bytes_moved = nml_ptr->cms->handle_to_global_data->total_bytes_moved; }}/*************************************************************** NML Reset Function* Can be used instead of deleting and recreating an NML channel.*************************************************************/int NML::reset(){ int cms_copy_ret = 0; if (valid()) { return 1; } if (NULL != cms) { // Recreate a CMS channel identitical to the old one, do not // re-read the config file. CMS *oldcms = cms; cms = NULL; cms_copy_ret = cms_copy(&cms, oldcms, 0, 0); if (cms_copy_ret < 0) { if (cms != NULL && cms != oldcms) { delete oldcms; } return 0; } register_with_server(); add_to_channel_list(); // FAST MODE is a combination of options which allow certian checks // during // a read or write operation to be avoided and therefore reduce the // NML/CMS // overhead. if (!cms->is_phantom && cms->ProcessType == CMS_LOCAL_TYPE && !cms->neutral && !cms->isserver && !cms->enable_diagnostics) { fast_mode = 1; } cms_status = (int *) &(cms->status); cms_inbuffer_header_size = &(cms->header.in_buffer_size); char *forced_type_eq = strstr(cms->buflineupper, "FORCE_TYPE="); if (forced_type_eq != NULL) { long temp = strtol(forced_type_eq + 11, NULL, 0); if (temp > 0) { forced_type = temp; fast_mode = 0; } } char *brpi_eq = strstr(cms->buflineupper, "BRPI="); if (brpi_eq != NULL) { blocking_read_poll_interval = strtod(brpi_eq + 5, NULL); } delete oldcms; } else { // Re-read the config file before creating a new CMS object. if (cms_config(&cms, bufname, procname, cfgfilename, 0, 0) < 0) { return 0; } } return valid();}/********************************************************** NML Destructor:* Notes:* 1. Use if(NULL != ???) to avoid deleting objects that were* never constructed.* 2. The delete channel function was added because an error occured in* running a server unded WIN32. An exception would occur as* the last NML channel was being deleted from within nml_cleanup.* After two days of being unable to debug this problem I* replaced the delete nml with nml->delete_channel() as a workaround.* The cause of this exception is still not understood.*********************************************************/NML::~NML(){ if (already_deleted) { if (verbose_nml_error_messages) { rcs_print_error("NML channel being deleted more than once.\n"); } } already_deleted = 1; delete_channel();}void NML::delete_channel(){ rcs_print_debug(PRINT_NML_DESTRUCTORS, "deleting NML (%d)\n", channel_list_id); if (NULL != cms_for_msg_string_conversions && cms != cms_for_msg_string_conversions) { delete cms_for_msg_string_conversions; cms_for_msg_string_conversions = 0; } if (NULL != cms) { rcs_print_debug(PRINT_NML_DESTRUCTORS, " delete (CMS *) %X;\n", cms); delete cms; cms = (CMS *) NULL; } if (NULL != format_chain) { delete format_chain; format_chain = (LinkedList *) NULL; } if (NULL != NML_Main_Channel_List && (0 != channel_list_id)) { NML_Main_Channel_List->delete_node(channel_list_id); } rcs_print_debug(PRINT_NML_DESTRUCTORS, "Leaving ~NML()\n");}/************************************************************** NML Member Function: get_address()* Purpose:* Returns the address of the local copy of the buffer.* Use this function instead of nml->cms->subdiv_data directly to prevent* users from pointing nml->cms->subdiv_data at something else. Or getting* a segmentation fault if cms was not properly constructed.***************************************************************/NMLmsg *NML::get_address(){ if (NULL == cms) { if (NULL != cms_for_msg_string_conversions) { return ((NMLmsg *) cms_for_msg_string_conversions->subdiv_data); } error_type = NML_INVALID_CONFIGURATION; return ((NMLmsg *) NULL); } else { return ((NMLmsg *) cms->subdiv_data); }}/************************************************************** NML Member Function: get_address_subdivision(int subdiv)* Purpose:* Returns the address of the local copy of the buffer.* Use this function instead of nml->cms->subdiv_data directly to prevent* users from pointing nml->cms->subdiv_data at something else. Or getting* a segmentation fault if cms was not properly constructed.***************************************************************/NMLmsg *NML::get_address_subdivision(int subdiv){ if (NULL == cms) { error_type = NML_INVALID_CONFIGURATION; return ((NMLmsg *) NULL); } else { cms->set_subdivision(subdiv); return ((NMLmsg *) cms->subdiv_data); }}/************************************************************** NML Member Function: get_address_subdivision(int subdiv)* Purpose:* Returns the total number of subdivisions configured for this* NML channel.***************************************************************/int NML::get_total_subdivisions(){ if (NULL == cms) { return (1); } else { return (cms->total_subdivisions); }}/************************************************************ NML Member Function: clear()* Purpose:* Clears the CMS buffer associated with this NML channel.** Returns:* 0 if no error occured or -1 if error occured.** Notes:* 1. Some buffers can be identified as PHANTOM in the config file.* this will cause cms->is_phantom to be set. This will cause this* function to call the function pointed to by phantom_clear* if it is not NULL rather than using CMS.* 2. If an error occurs, users can check error_type before* making any other NML calls************************************************************/int NML::clear(){ if (NULL == cms) { error_type = NML_INVALID_CONFIGURATION; return (-1); } else { if (cms->is_phantom) { if (NULL != phantom_clear) { return ((*phantom_clear) ()); } else { return (0);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -