Esempio n. 1
0
static void
ualarm_AST(Alarm *a)
{
    int iss;
    unsigned long now[2];

    iss = sys$gettim(now);
    if (VMSERR(iss)) lib$signal(iss);

    if (a->function == UAL_SET || a->function == UAL_CLEAR) {
        if (a0->function == UAL_ACTIVE) {
            iss = sys$cantim(a0,PSL$C_USER);
            if (VMSERR(iss)) lib$signal(iss);

            iss = lib$subx(a0->remain, now, a->remain);
            if (VMSERR(iss)) lib$signal(iss);

            if (a->remain[1] & 0x80000000) 
                a->remain[0] = a->remain[1] = 0;
        }

        if (a->function == UAL_SET) {
            a->function = a0->function;
            a0->function = UAL_ACTIVE;
            a0->repeat = a->repeat;
            if (a0->repeat) {
                a0->interval[0] = a->interval[0];
                a0->interval[1] = a->interval[1];
            }
            a0->delay[0] = a->delay[0];
            a0->delay[1] = a->delay[1];

            iss = lib$subx(now, a0->delay, a0->remain);
            if (VMSERR(iss)) lib$signal(iss);

            iss = sys$setimr(0,a0->delay,ualarm_AST,a0);
            if (VMSERR(iss)) lib$signal(iss);
        } else {
            a->function = a0->function;
            a0->function = UAL_NULL;
        }
        iss = sys$setef(alarm_ef);
        if (VMSERR(iss)) lib$signal(iss);
    } else if (a->function == UAL_ACTIVE) {
        if (a->repeat) {
            iss = lib$subx(now, a->interval, a->remain);
            if (VMSERR(iss)) lib$signal(iss);

            iss = sys$setimr(0,a->interval,ualarm_AST,a);
            if (VMSERR(iss)) lib$signal(iss);
        } else {
            a->function = UAL_NULL;
        }
        iss = sys$wake(0,0);
        if (VMSERR(iss)) lib$signal(iss);
        lib$signal(SS$_ASTFLT);
    } else {
        lib$signal(SS$_BADPARAM);
    }
}
Esempio n. 2
0
/*
 * ---------------------------------------------
 * System call to cancel timer.
 * ---------------------------------------------
 */
void cancel_timer(TID tid)
{
	/* An interrupt should never cancel a timer that has been started in the mainline code.
	 * Or else it is possible the mainline code might hibernate for ever.
	 * In VMS, interrupt is equivalent to being in an AST. Hence assert we are never in an AST if we are here.
	 * The only exception is if we are exiting in which case we are not going to be hibernating so it is ok.
	 */
	assert(!lib$ast_in_prog() || process_exiting);
	sys$cantim(tid, 0);
}
Esempio n. 3
0
/***********************************************************************
This routine is called to wait for a clustered data base to transition
to a new state.  If the "state" parameter is non-zero, then it is
considered a bit mask, with state zero being the lsb, etc.  (All of
these masks are symbolically defined in ccp.h as CCST_MASK_nnnnn.)
In this case we will return when the state is obtained.  If the
state is zero, we will return when the ccp_cycle count is bumped,
indicating that we have transitioned into read mode.  In any event
we will return after the "next" cycle has passed, so that if we
"miss" our window, we can try again.
***********************************************************************/
bool ccp_userwait(gd_region *reg, uint4 state, int4 *timadr, unsigned short cycle)
	/* if timadr is non-zero, then the timeout quadword, else use the seg's timeout interval */
{
	int4		status;
	static void	ccp_nocomm();
	bool		timer_on;
	sgmnt_data	*seg;
	sgmnt_addrs	*csa;
	int4		*timptr;
	char		buff[(MM_BLOCK - 1) * DISK_BLOCK_SIZE];
	short		iosb[4];
	error_def(ERR_CCPNOTFND);

	csa = &((vms_gds_info *)(reg->dyn.addr->file_cntl->file_info))->s_addrs;
	seg = ((vms_gds_info *)(reg->dyn.addr->file_cntl->file_info))->s_addrs.hdr;
	timptr = timadr ? timadr : (int4 *) &seg->ccp_response_interval;
	timer_on = timptr[0] != 0 && timptr[1] != 0;
	for (; ;)
	{	ccp_communication_timeout = FALSE;
		if (timer_on)
		{
			status = sys$setimr(0, timptr, ccp_nocomm, ccp_nocomm, 0);
			if ((status & 1) == 0)
				rts_error(VARLSTCNT(1) status);
		}
		while (!CCP_SEGMENT_STATE(csa->nl, state) && csa->nl->ccp_cycle == cycle && !ccp_communication_timeout)
		{
			sys$hiber();
		}

		if (ccp_communication_timeout && !(CCP_SEGMENT_STATE(csa->nl, state) || csa->nl->ccp_cycle != cycle))
		{
			status = sys$qiow(EFN$C_ENF, ((vms_gds_info *)(reg->dyn.addr->file_cntl->file_info))->fab->fab$l_stv,
								IO$_READVBLK, &iosb[0], 0, 0, buff, SIZEOF(buff), 1, 0, 0, 0);
			if ((status & 1) && (iosb[0] & 1) && ((sgmnt_data *)buff)->freeze)
				continue;
			rts_error(VARLSTCNT(1) ERR_CCPNOTFND);
		}else
			break;
	}
	if (timer_on)
		sys$cantim(ccp_nocomm,0);
	return CCP_SEGMENT_STATE(csa->nl, state);
}
Esempio n. 4
0
void	jnl_file_close(gd_region *reg, bool clean, bool dummy)
{
	jnl_file_header		header;
	sgmnt_addrs		*csa;
	jnl_private_control	*jpc;
	jnl_buffer_ptr_t	jb;
	struct_jrec_eof		eof_record;
	off_jnl_t		eof_addr;
	uint4			status;
	error_def		(ERR_PREMATEOF);
	error_def		(ERR_JNLCLOSE);
	error_def		(ERR_JNLWRERR);

	csa = &FILE_INFO(reg)->s_addrs;
	assert(csa->now_crit || (csa->hdr->clustered && (CCST_CLOSED == csa->nl->ccp_state)));
	ASSERT_JNLFILEID_NOT_NULL(csa)
	jpc = csa->jnl;
#if defined(UNIX)
	if (csa->dbsync_timer)
	{
		cancel_timer((TID)csa);
		csa->dbsync_timer = FALSE;
	}
#elif defined(VMS)
	/* See comment about ordering of the two statements below, in similar code in gds_rundown */
	if (csa->dbsync_timer)
	{
		csa->dbsync_timer = FALSE;
		++astq_dyn_avail;
	}
	sys$cantim(csa, PSL$C_USER);	/* cancel all dbsync-timers for this region */
#endif
	if ((NULL == jpc) || (NOJNL == jpc->channel))
		return;
	if (clean)
	{
		jb = jpc->jnl_buff;
		jnl_write_eof_rec(csa, &eof_record);
		jnl_flush(reg);
		assert(jb->dskaddr == jb->freeaddr);
		UNIX_ONLY(jnl_fsync(reg, jb->dskaddr);)
		UNIX_ONLY(assert(jb->freeaddr == jb->fsync_dskaddr);)
Esempio n. 5
0
/*
 * ------------------------------------------------------
 * Start hibernating by starting a timer using hiber_time
 * (in msecs) and doing a pause
 * ------------------------------------------------------
 */
void hiber_start(uint4 hiber)
{
	int4 	hiber_time[2];	/* don't have static since can be interrupted by an AST */
	int	status_timr, status_wait, ast_in_prog;

	if (0 == hiber)
		return;	/* in PRO code return */

	hiber_time[0] = -time_low_ms((int4)hiber);
	hiber_time[1] = -time_high_ms((int4)hiber);
	if (hiber_time[1] == 0)
		hiber_time[1] -= 1;

	if (0 != (ast_in_prog = lib$ast_in_prog()))
	{	/* sleep sounder but less permanently;
		 * note that an AST may cause an inappropriate time to be used for another hiber_start in progress,
		 * but that risk should be statistically small, and the consequences (as far as known) are not important
		 */
		status_timr = sys$setimr(efn_timer_ast, hiber_time, 0, hiber_start_ast, 0);
		assert(SS$_NORMAL == status_timr);
		if (SS$_NORMAL == status_timr)
		{
			status_wait = sys$waitfr(efn_timer_ast);
			assert(SS$_NORMAL == status_wait);
		}
	} else
	{ /* timr->hiber should not be changed to timr->waitfr. The former waits for a wakeup or outofband event; whichever
	   * happens sooner will stop the hiber while the latter does not recognize outofband events (like tp timeouts)
	   */
		status_timr = sys$setimr(efn_hiber_start, hiber_time, wake, hiber_start, 0);
		assert(SS$_NORMAL == status_timr);
		if (SS$_NORMAL == status_timr)
		{
			sys$hiber();
			sys$cantim(hiber_start, 0);
		}
	}
}
Esempio n. 6
0
/*
**++
**  ROUTINE:	netlib_read
**
**  FUNCTIONAL DESCRIPTION:
**
**  	tbs
**
**  RETURNS:	cond_value, longword (unsigned), write only, by value
**
**  PROTOTYPE:
**
**  	tbs
**
**  IMPLICIT INPUTS:	None.
**
**  IMPLICIT OUTPUTS:	None.
**
**  COMPLETION CODES:
**
**
**  SIDE EFFECTS:   	None.
**
**--
*/
unsigned int netlib_read (struct CTX **xctx, struct dsc$descriptor *dsc,
    	    	    	    struct SINDEF *sa, unsigned int *sasize,
    	    	    	    unsigned int *salen, TIME *timeout,
    	    	    	    struct NETLIBIOSBDEF *iosb,
    	    	    	    void (*astadr)(), void *astprm) {
    struct CTX *ctx;
    struct IOR *ior;
    unsigned int status;
    ITMLST sname;
    int argc, do_from;

    VERIFY_CTX(xctx, ctx);
    SETARGCOUNT(argc);

    if (dsc->dsc$b_dtype != DSC$K_DTYPE_T && dsc->dsc$b_dtype != 0)
    	return SS$_BADPARAM;
    if (dsc->dsc$b_class == DSC$K_CLASS_D) {
	if (dsc->dsc$w_length == 0) return SS$_BADPARAM;
    } else {
    	if (dsc->dsc$b_class != DSC$K_CLASS_S && dsc->dsc$b_class != 0)
    	return SS$_BADPARAM;
    }

    do_from = (argc > 3 && sa != 0 && sasize != 0 && *sasize != 0);
    if (argc > 7 && astadr != 0) {
    	struct IOR *ior;
    	GET_IOR(ior, ctx, iosb, astadr, (argc > 8) ? astprm : 0);
    	if (do_from) ITMLST_INIT(sname, 0, sizeof(struct SINDEF),
    	    	    &ior->specior.from, &ior->specior.fromlen);
    	if (do_from) {
    	    ior->spec_userfrom = sa;
    	    ior->spec_length = *sasize;
    	    ior->spec_retlen = salen;
    	    ior->iorflags = IOR_M_COPY_FROM;
    	} else ior->iorflags = 0;
    	if (timeout != 0) {
    	    ior->iorflags |= IOR_M_IO_TIMED;
    	    status = sys$setimr(netlib_asynch_efn, timeout, io_timeout, ior);
    	    if (!OK(status)) {
    	    	FREE_IOR(ior);
    	    	return status;
    	    }
    	}

    	status = sys$qio(netlib_asynch_efn, ctx->chan, IO$_READVBLK, &ior->iosb,
    	    	    	    io_completion, ior, dsc->dsc$a_pointer,
    	    	    	    dsc->dsc$w_length, do_from ? &sname : 0, 0, 0, 0);
    	if (!OK(status)) {
    	    if (timeout != 0) sys$cantim(ior, 0);
    	    FREE_IOR(ior);
    	}
    } else {
    	struct NETLIBIOSBDEF myiosb;
    	struct SINDEF from;
    	unsigned short fromlen;
    	int timed_out;

    	if (do_from) ITMLST_INIT(sname, 0, sizeof(struct SINDEF),
    	    	    &from, &fromlen);

    	timed_out = 0;
    	if (argc > 5 && timeout != 0) {
    	    GET_IOR(ior, ctx, 0, 0, 0);
    	    ior->iorflags = IOR_M_IO_TIMED;
    	    status = sys$setimr(netlib_asynch_efn, timeout, io_timeout, ior);
    	    if (!OK(status)) {
    	    	FREE_IOR(ior);
    	    	return status;
    	    }
    	}
    	status = sys$qiow(netlib_synch_efn, ctx->chan, IO$_READVBLK,
    	    	    	    &myiosb, 0, 0,
    	    	    	    dsc->dsc$a_pointer, dsc->dsc$w_length,
    	    	    	    do_from ? &sname : 0, 0, 0, 0);
    	if (argc > 5 && timeout != 0) {
    	    sys$cantim(ior, 0);
    	    timed_out = ior->iorflags & IOR_M_IO_TIMEOUT;
    	    FREE_IOR(ior);
    	}
    	if (OK(status)) {
    	    if (timed_out && myiosb.iosb_w_status == SS$_CANCEL)
    	    	myiosb.iosb_w_status = SS$_TIMEOUT;
    	    status = netlib___cvt_status(&myiosb);
    	}
    	if (argc > 6 && iosb != 0) netlib___cvt_iosb(iosb, &myiosb);
    	if (OK(status) && do_from) {
    	    unsigned int len;
    	    len = fromlen;
    	    if (len > *sasize) len = *sasize;
    	    memcpy(sa, &from, len);
    	    if (argc > 4 && salen != 0) *salen = len;
    	}
    }

    return status;

} /* netlib_read */
Esempio n. 7
0
/*
**++
**  ROUTINE:	io_completion
**
**  FUNCTIONAL DESCRIPTION:
**
**  	tbs
**
**  RETURNS:	cond_value, longword (unsigned), write only, by value
**
**  PROTOTYPE:
**
**  	tbs
**
**  IMPLICIT INPUTS:	None.
**
**  IMPLICIT OUTPUTS:	None.
**
**  COMPLETION CODES:
**
**
**  SIDE EFFECTS:   	None.
**
**--
*/
static unsigned int io_completion (struct IOR *ior) {

    struct CTX *ctx = ior->ctx;

    ior->iorflags |= IOR_M_IO_COMPLETED;

    if (ior->iorflags & IOR_M_IO_TIMED) sys$cantim(ior, 0);

    if (ior->iosb.iosb_w_status == SS$_CANCEL && (ior->iorflags & IOR_M_IO_TIMEOUT))
    	ior->iosb.iosb_w_status = SS$_TIMEOUT;

    if (ior->iosbp != 0) netlib___cvt_iosb(ior->iosbp, &ior->iosb);


    if (ior->iorflags & IOR_M_COPY_LENGTH) {
    	if (OK(ior->iosb.iosb_w_status) && ior->spec_retlen != 0)
    	    	*(unsigned int *) ior->spec_retlen = ior->spec_length;
    	ior->iorflags &= ~IOR_M_COPY_LENGTH;
    }

    if (ior->iorflags & IOR_M_COPY_FROM) {
    	if (OK(ior->iosb.iosb_w_status) && ior->spec_userfrom != 0) {
    	    unsigned int len;
    	    len = ior->specior.fromlen;
    	    if (len > ior->spec_length) len = ior->spec_length;
    	    memcpy(ior->spec_userfrom, &ior->specior.from, len);
    	    if (ior->spec_retlen != 0) *(unsigned int *)ior->spec_retlen = len;
    	 }
    	 ior->iorflags &= ~IOR_M_COPY_FROM;
    }

    if (ior->iorflags & IOR_M_COPY_ADDRS) {
    	struct HOSTENT *h;

    	h = ior->spec_hostent;
    	if (OK(ior->iosb.iosb_w_status)) {
    	    char *base;
    	    unsigned int *offlst;
    	    int i;
    	    base = (char *) h;
    	    i = 0;
    	    if (h->addrlist_offset != 0) {
    	    	struct INADDRDEF *alist = ior->spec_useralist;
    	    	offlst = (unsigned int *) (base+h->addrlist_offset);
    	    	while (i < ior->spec_length && offlst[i] != 0) {
    	    	    alist[i] = *(struct INADDRDEF *) (base + offlst[i]);
    	    	    i++;
    	    	}
    	    }
    	    if (ior->spec_retlen != 0) *(unsigned int *)ior->spec_retlen = i;
    	}
    	lib$free_vm(&hostent_size, &h);
    	ior->iorflags &= ~IOR_M_COPY_ADDRS;
    }

    if (ior->iorflags & IOR_M_COPY_HOSTNAME) {
    	struct HOSTENT *h;
    	h = ior->spec_hostent;
    	if (OK(ior->iosb.iosb_w_status)) {
    	    str$copy_r(ior->spec_usrdsc, &ior->specior.fromlen,
    	    	    	    	    	h->buffer);
    	    if (ior->spec_retlen != 0)
    	    	*(unsigned short *)ior->spec_retlen =
    	    	    	    	    	    	ior->specior.fromlen;
    	}
    	lib$free_vm(&hostent_size, &h);
    	ior->iorflags &= ~IOR_M_COPY_HOSTNAME;
    }

    if (ior->iorflags & IOR_M_NEW_CONTEXT) {
    	if (OK(ior->iosb.iosb_w_status)) {
    	    *(struct CTX **) ior->spec_xnewctx = ior->spec_newctx;
    	} else {
    	    sys$dassgn(((struct CTX *)ior->spec_newctx)->chan);
    	    netlib___free_ctx((struct CTX *) ior->spec_newctx);
    	}
    	   ior->iorflags &= ~IOR_M_NEW_CONTEXT;
    }

    if (ior->astadr != 0) (*(ior->astadr))(ior->astprm);

    FREE_IOR(ior);

    return SS$_NORMAL;

} /* io_completion */
Esempio n. 8
0
/*
 * ------------------------------------------
 * Hang the process for a specified time.
 *
 *	Goes to sleep for a positive value.
 *	Any caught signal will terminate the sleep
 *	following the execution of that signal's catching routine.
 *
 * 	The actual hang duration should be NO LESS than the specified
 * 	duration for specified durations greater than .001 seconds.
 * 	Certain applications depend on this assumption.
 *
 * Arguments:
 *	num - time to sleep
 *
 * Return:
 *	none
 * ------------------------------------------
 */
void op_hang(mval* num)
{
	int		ms;
	double		tmp;
	mv_stent	*mv_zintcmd;
	ABS_TIME	cur_time, end_time;
#	ifdef VMS
	uint4 		time[2];
	int4		efn_mask, status;
#	endif
	DCL_THREADGBL_ACCESS;

	SETUP_THREADGBL_ACCESS;
	ms = 0;
	MV_FORCE_NUM(num);
	if (num->mvtype & MV_INT)
	{
		if (0 < num->m[1])
		{
			assert(MV_BIAS >= 1000);	/* if formats change overflow may need attention */
			ms = num->m[1] * (1000 / MV_BIAS);
		}
	} else if (0 == num->sgn) 		/* if sign is not 0 it means num is negative */
	{
		tmp = mval2double(num) * (double)1000;
		ms = ((double)MAXPOSINT4 >= tmp) ? (int)tmp : (int)MAXPOSINT4;
	}
	if (ms)
	{
		if (TREF(tpnotacidtime) * 1000 < ms)
			TPNOTACID_CHECK(HANGSTR);
#		if defined(DEBUG) && defined(UNIX)
		if (WBTEST_ENABLED(WBTEST_DEFERRED_TIMERS) && (3 > gtm_white_box_test_case_count) && (123000 == ms))
		{
			DEFER_INTERRUPTS(INTRPT_NO_TIMER_EVENTS);
			DBGFPF((stderr, "OP_HANG: will sleep for 20 seconds\n"));
			LONG_SLEEP(20);
			DBGFPF((stderr, "OP_HANG: done sleeping\n"));
			ENABLE_INTERRUPTS(INTRPT_NO_TIMER_EVENTS);
			return;
		}
		if (WBTEST_ENABLED(WBTEST_BREAKMPC)&& (0 == gtm_white_box_test_case_count) && (999 == ms))
		{
			frame_pointer->old_frame_pointer->mpc = (unsigned char *)GTM64_ONLY(0xdeadbeef12345678)
				NON_GTM64_ONLY(0xdead1234);
			return;
		}
		if (WBTEST_ENABLED(WBTEST_UTIL_OUT_BUFFER_PROTECTION) && (0 == gtm_white_box_test_case_count) && (999 == ms))
		{	/* Upon seeing a .999s hang this white-box test launches a timer that pops with a period of
		 	 * UTIL_OUT_SYSLOG_INTERVAL and prints a long message via util_out_ptr.
			 */
			start_timer((TID)&util_out_syslog_dump, UTIL_OUT_SYSLOG_INTERVAL, util_out_syslog_dump, 0, NULL);
			return;
		}
#		endif
		sys_get_curr_time(&cur_time);
		mv_zintcmd = find_mvstent_cmd(ZINTCMD_HANG, restart_pc, restart_ctxt, FALSE);
		if (!mv_zintcmd)
			add_int_to_abs_time(&cur_time, ms, &end_time);
		else
		{
			end_time = mv_zintcmd->mv_st_cont.mvs_zintcmd.end_or_remain;
			cur_time = sub_abs_time(&end_time, &cur_time);	/* get remaing time to sleep */
			if (0 <= cur_time.at_sec)
				ms = (int4)(cur_time.at_sec * 1000 + cur_time.at_usec / 1000);
			else
				ms = 0;		/* all done */
			/* restore/pop previous zintcmd_active[ZINTCMD_HANG] hints */
			TAREF1(zintcmd_active, ZINTCMD_HANG).restart_pc_last = mv_zintcmd->mv_st_cont.mvs_zintcmd.restart_pc_prior;
			TAREF1(zintcmd_active, ZINTCMD_HANG).restart_ctxt_last
				= mv_zintcmd->mv_st_cont.mvs_zintcmd.restart_ctxt_prior;
			TAREF1(zintcmd_active, ZINTCMD_HANG).count--;
			assert(0 <= TAREF1(zintcmd_active, ZINTCMD_HANG).count);
			if (mv_chain == mv_zintcmd)
				POP_MV_STENT();	/* just pop if top of stack */
			else
			{	/* flag as not active */
				mv_zintcmd->mv_st_cont.mvs_zintcmd.command = ZINTCMD_NOOP;
				mv_zintcmd->mv_st_cont.mvs_zintcmd.restart_pc_check = NULL;
			}
			if (0 == ms)
				return;		/* done HANGing */
		}
#		ifdef UNIX
		if (ms < 10)
			SLEEP_USEC(ms * 1000, TRUE);	/* Finish the sleep if it is less than 10ms. */
		else
			hiber_start(ms);
#		elif defined(VMS)
		time[0] = -time_low_ms(ms);
		time[1] = -time_high_ms(ms) - 1;
		efn_mask = (1 << efn_outofband | 1 << efn_timer);
		if (SS$_NORMAL != (status = sys$setimr(efn_timer, &time, NULL, &time, 0)))
			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(8) ERR_SYSCALL, 5, RTS_ERROR_LITERAL("$setimr"), CALLFROM, status);
		if (SS$_NORMAL != (status = sys$wflor(efn_outofband, efn_mask)))
			rts_error_csa(CSA_ARG(NULL) VARLSTCNT(8) ERR_SYSCALL, 5, RTS_ERROR_LITERAL("$wflor"), CALLFROM, status);
		if (outofband)
		{
			if (SS$_WASCLR == (status = sys$readef(efn_timer, &efn_mask)))
			{
				if (SS$_NORMAL != (status = sys$cantim(&time, 0)))
					rts_error_csa(CSA_ARG(NULL) VARLSTCNT(8) ERR_SYSCALL, 5, RTS_ERROR_LITERAL("$cantim"),
						CALLFROM, status);
			} else
				assertpro(SS$_WASSET == status);
		}
#		endif
	} else
		rel_quant();
	if (outofband)
	{
		PUSH_MV_STENT(MVST_ZINTCMD);
		mv_chain->mv_st_cont.mvs_zintcmd.end_or_remain = end_time;
		mv_chain->mv_st_cont.mvs_zintcmd.restart_ctxt_check = restart_ctxt;
		mv_chain->mv_st_cont.mvs_zintcmd.restart_pc_check = restart_pc;
		/* save current information from zintcmd_active */
		mv_chain->mv_st_cont.mvs_zintcmd.restart_ctxt_prior = TAREF1(zintcmd_active, ZINTCMD_HANG).restart_ctxt_last;
		mv_chain->mv_st_cont.mvs_zintcmd.restart_pc_prior = TAREF1(zintcmd_active, ZINTCMD_HANG).restart_pc_last;
		TAREF1(zintcmd_active, ZINTCMD_HANG).restart_pc_last = restart_pc;
		TAREF1(zintcmd_active, ZINTCMD_HANG).restart_ctxt_last = restart_ctxt;
		TAREF1(zintcmd_active, ZINTCMD_HANG).count++;
		mv_chain->mv_st_cont.mvs_zintcmd.command = ZINTCMD_HANG;
		outofband_action(FALSE);
	}
	return;
}
Esempio n. 9
0
pwr_tUInt32 bck_WaitBackup (
		void *context,
		pwr_tBoolean timeout)
{
  pwr_tUInt32 sts;
  pwr_tObjid objid;
  pwr_tInt32 c;
  pwr_tTime t;
  pwr_tVaxTime tmo;
  pwr_tVaxTime tmptime;
  pwr_sClass_Backup_Conf *backup_confp;	/* Backup_Conf object pointer */
  $DESCRIPTOR (timeunitdsc, "0 0:0:0.1");	/* 0.1 second units */
  int cycletime;

#ifdef OS_ELN
  pwr_tInt32 res;
  pwr_tVaxTime *tmop;
#endif

#ifdef OS_VMS
  $DESCRIPTOR (efcname, BCK_EFC_NAME);
#endif

/*
 * Initialize
 */

#ifdef OS_ELN
  if (!areas_mapped) {
    BCK_MAP_AREAS;
    areas_mapped = TRUE;
  }
#endif

/*
 * Find the local Backup_Conf object
 */

  sts = gdh_GetClassList (pwr_cClass_Backup_Conf, &objid);
  while (ODD (sts)) {
    sts = gdh_ObjidToPointer (objid, (pwr_tAddress *)&backup_confp);
    if (ODD (sts)) break;
    sts = gdh_GetNextObject (objid, &objid);
  }
  if (EVEN (sts)) return sts;		/* Something wrong, quit */

/*
 * Pick up argument information
 */

  if (context == NULL) time_GetTime(&t);
  else {
    t = *(pwr_tTime *)context;
    free (context);
  }

#ifdef OS_ELN
  tmop = NULL;
#else
  timed_out = FALSE;  
  sts = sys$ascefc (BCK_EFC, &efcname, 0, 0);
  if (EVEN (sts)) lib$signal (sts);			/* BUG */
#endif

  if (timeout) {
    cycletime = backup_confp->CycleSlow * 2;
    if (cycletime == 0) cycletime = BCK_DEFAULT_SLOW * 2;

#ifdef OS_ELN
    tmo = eln$time_value (&timeunitdsc);
#else
    sts = sys$bintim (&timeunitdsc, &tmo);
    if (EVEN (sts)) lib$signal (sts);		/* BUG, should not happen */
#endif

    lib$mult_delta_time (
		&cycletime,		/* multiplier */
		&tmo);			/* delta_time (modified) */
    sys$gettim (&tmptime);
    lib$add_times (&tmo, &tmptime, &tmo); /* Make absolute time */

#ifdef OS_ELN
    tmop = &tmo;
#else
    sts = sys$setimr (BCK_WRITE_DONE, &tmo, &astrtn, 4711, 0);
    if (EVEN (sts)) lib$signal (sts);			/* BUG */
#endif
  }

/*
 * Loop, and wait for things to happen
 */

  while (TRUE) {
#ifdef OS_ELN
    ker$clear_event (NULL, bck_write_done);
    ker$wait_any (NULL, &res, tmop, bck_write_done);

    /* Check for timeout */

    if (res == 0) return SS$_TIMEOUT;
#else

    sts = sys$clref (BCK_WRITE_DONE);
    if (EVEN (sts)) lib$signal (sts);			/* BUG */
    sts = sys$waitfr (BCK_WRITE_DONE);
    if (EVEN (sts)) lib$signal (sts);			/* BUG */

    /* Check for timeout */

    if (timed_out) return SS$_TIMEOUT;

#endif

    /* Check if both cycles done */

    if (time_Acomp(&backup_confp->ObjTimeSlow, &t) < 0) 
        continue;
    if (time_Acomp(&backup_confp->ObjTimeFast, &t) < 0) 
        continue;

    break;

  } /* Loop */

#ifdef OS_VMS
  sys$cantim (4711, 0);
#endif

  return 1;	/* Done. */

} /* bck_WaitBackup */
Esempio n. 10
0
void	ccp_close1(ccp_db_header *db)
{
	ccp_db_header		*db0, *db1;
	ccp_que_entry		*que_ent;
	ccp_relque		*que_hd;
	mem_list		*ml_ptr, *ml_ptr_hold;
	sgmnt_addrs		*csa;
	vms_gds_info		*gds_info;
	unsigned char		section_name[GLO_NAME_MAXLEN];
	uint4			retadr[2], status, outaddrs[2];
	struct dsc$descriptor_s name_dsc;


	if (ccp_stop)
		ccp_stop_ctr--;

	if (db->stale_in_progress)
		sys$cantim(&db->stale_timer_id, PSL$C_USER);

	ccp_quemin_adjust(CCP_CLOSE_REGION);

	sys$cantim(&db->tick_timer_id, PSL$C_USER);
	sys$cantim(&db->quantum_timer_id, PSL$C_USER);

	db->segment->nl->ccp_state = CCST_CLOSED;
	db->wmexit_requested = TRUE;	/* ignore any blocking ASTs - already releasing */

	gds_info = FILE_INFO(db->greg);

	if (JNL_ENABLED(db->glob_sec))
	{
		if (db->segment->jnl != NULL  &&  db->segment->jnl->channel != 0)
		{
			status = sys$setimr(0, delta_1_sec, ccp_close_timeout, &db->close_timer_id, 0);
			if (status != SS$_NORMAL)
				ccp_signal_cont(status);	/***** Is this reasonable? *****/
			status = ccp_enqw(EFN$C_ENF, LCK$K_EXMODE, &db->wm_iosb, LCK$M_CONVERT | LCK$M_NOQUEUE, NULL, 0,
					  NULL, 0, NULL, PSL$C_USER, 0);
			if (status == SS$_NOTQUEUED)
				/* We're not the only node accessing the journal file */
				jnl_file_close(db->greg, FALSE, FALSE);
			else
			{
				/***** Check error status here? *****/
				if (db->segment->jnl->jnl_buff->before_images  &&
				    db->segment->ti->curr_tn > db->segment->jnl->jnl_buff->epoch_tn)
				{
					csa = db->segment;
					JNL_SHORT_TIME(jgbl.gbl_jrec_time);	/* needed for jnl_put_jrt_pini()
											and jnl_write_epoch_rec() */
					if (0 == csa->jnl->pini_addr)
						jnl_put_jrt_pini(csa);
					db->segment->jnl->jnl_buff->epoch_tn = db->segment->ti->curr_tn;
					jnl_write_epoch_rec(db->segment);
				}
				jnl_file_close(db->greg, TRUE, FALSE);
			}
			sys$cantim(&db->close_timer_id, PSL$C_USER);
			status = gtm_deq(gds_info->s_addrs.jnl->jnllsb->lockid, NULL, PSL$C_USER, 0);
			if (status != SS$_NORMAL)
				ccp_signal_cont(status);	/***** Is this reasonable? *****/
		}
	}

	db->segment = NULL;	/* Warn AST's that the segment has been deleted */

	status = sys$deq(db->lock_iosb.lockid, NULL, PSL$C_USER, LCK$M_CANCEL);
	if (status != SS$_NORMAL  &&  status != SS$_CANCELGRANT)
		ccp_signal_cont(status);	/***** Is this reasonable? *****/

	status = sys$deq(db->refcnt_iosb.lockid, NULL, PSL$C_USER, LCK$M_CANCEL);
	if (status != SS$_NORMAL  &&  status != SS$_CANCELGRANT)
		ccp_signal_cont(status);	/***** Is this reasonable? *****/

	status = sys$deq(db->wm_iosb.lockid, NULL, PSL$C_USER, LCK$M_CANCEL);
	if (status != SS$_NORMAL  &&  status != SS$_CANCELGRANT)
		ccp_signal_cont(status);	/***** Is this reasonable? *****/

	status = sys$deq(db->flush_iosb.lockid, NULL, PSL$C_USER, LCK$M_CANCEL);
	if (status != SS$_NORMAL  &&  status != SS$_CANCELGRANT)
		ccp_signal_cont(status);	/***** Is this reasonable? *****/

	status = sys$cancel(gds_info->fab->fab$l_stv);
	if (status != SS$_NORMAL)
		ccp_signal_cont(status);	/***** Is this reasonable? *****/

	status = sys$dassgn(gds_info->fab->fab$l_stv);
	if (status != SS$_NORMAL)
		ccp_signal_cont(status);	/***** Is this reasonable? *****/

	csa = &gds_info->s_addrs;

	outaddrs[0] = csa->db_addrs[0] - OS_PAGE_SIZE;	/* header no access page */
	outaddrs[1] = csa->db_addrs[1] + OS_PAGE_SIZE;	/* trailer no access page */
	if (FALSE == is_va_free(outaddrs[0]))
		gtm_deltva(outaddrs, NULL, PSL$C_USER);
	if (status != SS$_NORMAL)
		ccp_signal_cont(status);	/***** Is this reasonable? *****/

	status = sys$cretva(csa->db_addrs, retadr, PSL$C_USER);
	if (status != SS$_NORMAL)
		ccp_signal_cont(status);	/***** Is this reasonable? *****/
	assert(retadr[0] == csa->db_addrs[0]  &&  retadr[1] == csa->db_addrs[1]);

	ml_ptr_hold=db->mem_ptr;

	if (ml_ptr_hold->prev != NULL)
	{
		/* if prior segment is adjacent and free, coalesce the segments */
		if (ml_ptr_hold->prev->free  &&
		    ml_ptr_hold->addr == ml_ptr_hold->prev->addr + OS_PAGELET_SIZE * ml_ptr_hold->prev->pages)
		{
			ml_ptr = ml_ptr_hold->prev;
			ml_ptr->next = ml_ptr_hold->next;
			if (ml_ptr->next != NULL)
				ml_ptr->next->prev = ml_ptr;
			ml_ptr->pages += ml_ptr_hold->pages;
			free(ml_ptr_hold);
			ml_ptr_hold = ml_ptr;
		}
	}

	if (ml_ptr_hold->next != NULL)
	{
		/* if next segment is adjacent and free, coalesce the segments */
		if (ml_ptr_hold->next->free  &&
		    ml_ptr_hold->next->addr == ml_ptr_hold->addr + OS_PAGELET_SIZE * ml_ptr_hold->pages)
		{
			ml_ptr = ml_ptr_hold->next;
			ml_ptr_hold->next = ml_ptr->next;
			if (ml_ptr_hold->next != NULL)
				ml_ptr_hold->next->prev = ml_ptr_hold;
			ml_ptr_hold->pages += ml_ptr->pages;
			free(ml_ptr);
		}
	}

	ml_ptr_hold->free = TRUE;

	global_name("GT$S", &gds_info->file_id, section_name);
	name_dsc.dsc$a_pointer = &section_name[1];
	name_dsc.dsc$w_length = section_name[0];
	name_dsc.dsc$b_dtype = DSC$K_DTYPE_T;
	name_dsc.dsc$b_class = DSC$K_CLASS_S;
	status = del_sec(SEC$M_SYSGBL, &name_dsc, NULL);
	if (status != SS$_NORMAL)
		ccp_signal_cont(status);	/***** Is this reasonable? *****/

	/* Dequeue locks after delete section in ccp_close,
	   acquire lock before create section in gvcst_init,
	   release lock after delete section in gds_rundown   */

	status = gtm_deq(db->lock_iosb.lockid, NULL, PSL$C_USER, 0);
	if (status != SS$_NORMAL)
		ccp_signal_cont(status);	/***** Is this reasonable? *****/

	status = gtm_deq(db->refcnt_iosb.lockid, NULL, PSL$C_USER, 0);
	if (status != SS$_NORMAL)
		ccp_signal_cont(status);	/***** Is this reasonable? *****/

	status = gtm_deq(db->wm_iosb.lockid, NULL, PSL$C_USER, 0);
	if (status != SS$_NORMAL)
		ccp_signal_cont(status);	/***** Is this reasonable? *****/

	status = gtm_deq(db->flush_iosb.lockid, NULL, PSL$C_USER, 0);
	if (status != SS$_NORMAL)
		ccp_signal_cont(status);	/***** Is this reasonable? *****/

	que_hd = &ccp_action_que[PRIORITY];
	for (que_ent = (char *)que_hd + que_hd->bl;  que_ent != que_hd;  que_ent = (char *)que_ent + que_ent->q.bl)
		if (que_ent->value.v.h == db)
			que_ent->value.v.h = 0;

	free(gds_info->fab->fab$l_nam);
	free(gds_info->fab);
	free(db->greg->dyn.addr);
	free(db->greg);

	/* Remove db from list, this list should never be changed in an AST */
	for (db0 = ccp_reg_root, db1 = NULL;  db0 != db;  db1 = db0, db0 = db0->next)
		;
	if (db1 == NULL)
		ccp_reg_root = db0->next;
	else
		db1->next = db0->next;

	free(db);

	return;
}