Esempio n. 1
0
File: dpgbldir.c Progetto: 5HT/mumps
void gd_rundown(void)		/* Wipe out the global directory structures */
{
	gd_addr		*gda_cur, *gda_next;
	gdr_name	*gdn_cur, *gdn_next;

	for (gda_cur = gd_addr_head;  NULL != gda_cur; gda_cur = gda_next)
	{
		gda_next = gda_cur->link;
		if (gda_cur->end)
		{
			gd_ht_kill(gda_cur->tab_ptr, TRUE);
			free(gda_cur->tab_ptr);		/* free up hashtable malloced in gd_load() */
			free(gda_cur->id);		/* free up gd_id malloced in gd_load()/fill_gd_addr_id() */
			free((char *)gda_cur - sizeof(header_struct));	/* free up global directory itself */
		} else
			free(gda_cur);	/* GT.CM gd_addr and hence header_struct wasn't malloced in cm_add_gdr_ptr */
	}
	assert(NULL == gv_target_list);
	gd_header = gd_addr_head = (gd_addr *)NULL;
	for (gdn_cur = gdr_name_head; NULL != gdn_cur; gdn_cur = gdn_next)
	{
		gdn_next = (gdr_name *)gdn_cur->link;
		if (gdn_cur->name.len)
			free(gdn_cur->name.addr);
		free(gdn_cur);
	}
	gdr_name_head = (gdr_name *)NULL;
}
Esempio n. 2
0
void gtcmd_rundown(connection_struct *cnx, bool clean_exit)
{
	int4			link;
	cm_region_list		*ptr, *last, *que_next, *que_last;
	cm_region_head		*region;
	uint4			jnl_status;
	jnl_private_control	*jpc;
	jnl_buffer_ptr_t	jbp;
	int			refcnt;
	boolean_t		was_crit;
	int4			rundown_status = EXIT_NRM;			/* if gds_rundown went smoothly */

	for (ptr = cnx->region_root;  ptr;)
	{
		region = ptr->reghead;
		TP_CHANGE_REG(region->reg);
		jpc = cs_addrs->jnl;
		if (ptr->pini_addr && clean_exit && JNL_ENABLED(cs_data) && (NOJNL != jpc->channel))
		{
			was_crit = cs_addrs->now_crit;
			if (!was_crit)
				grab_crit(gv_cur_region);
			if (JNL_ENABLED(cs_data))
			{
				jpc->pini_addr = ptr->pini_addr;
				SET_GBL_JREC_TIME; /* jnl_ensure_open/jnl_put_jrt_pfin needs this to be set */
				jbp = jpc->jnl_buff;
				/* Before writing to jnlfile, adjust jgbl.gbl_jrec_time if needed to maintain time order
				 * of jnl records.  This needs to be done BEFORE the jnl_ensure_open as that could write
				 * journal records (if it decides to switch to a new journal file).
				 */
				ADJUST_GBL_JREC_TIME(jgbl, jbp);
				jnl_status = jnl_ensure_open();
				if (0 == jnl_status)
				{
					if (0 != jpc->pini_addr)
						jnl_put_jrt_pfin(cs_addrs);
				} else
					send_msg(VARLSTCNT(6) jnl_status, 4, JNL_LEN_STR(cs_data), DB_LEN_STR(gv_cur_region));
			}
			if (!was_crit)
				rel_crit(gv_cur_region);
		}
		refcnt = --region->refcnt;
		/* Dont know how refcnt can become negative but in pro handle it by bypassing this region. The reason is the
		 * following. refcnt should have originally been a positive value. Every time this function is invoked, it would
		 * be decremented by one. There should have been one invocation that saw refcnt to be zero. That would have
		 * done the rundown of the region or if it is still in the stack the rundown is still in progress. Therefore
		 * it is not a good idea to try running down this region when we see refcnt to be negative (as otherwise we
		 * will get confused and could potentially end up with SIG-11 or ACCVIO errors). The worst case is that we
		 * would not have rundown the region in which case an externally issued MUPIP RUNDOWN would be enough.
		 */
		assert(0 <= refcnt);
		if (0 == refcnt)
		{	/* free up only as little as needed to facilitate structure reuse when the region is opened again */
			assert(region->head.fl == region->head.bl);
			VMS_ONLY(gtcm_ast_avail++);
			if (JNL_ALLOWED(cs_data))
				jpc->pini_addr = 0;
			UNIX_ONLY(rundown_status |=) gds_rundown();
			gd_ht_kill(region->reg_hash, TRUE);	/* TRUE to free up the table and the gv_targets it holds too */
			FREE_CSA_DIR_TREE(cs_addrs);
			cm_del_gdr_ptr(gv_cur_region);
		}
		que_next = (cm_region_list *)((unsigned char *)ptr + ptr->regque.fl);
		que_last = (cm_region_list *)((unsigned char *)ptr + ptr->regque.bl);
		link = (int4)((unsigned char *)que_next - (unsigned char *)que_last);
		que_last->regque.fl = link;
		que_next->regque.bl = -link;
		last = ptr;
		ptr = ptr->next;
		free(last);
	}