⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ndet_loop.c

📁 操作系统SunOS 4.1.3版本的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
	ntfy_assert(n == 0, "Unexpected error: gettimeofday");	/* enum_itimer.min_tv is initialized in ndet_update_itimer. */	/* Determine and set process real itimer */	ndet_update_itimer(&enum_itimer);}static struct timeval NDET_END_OF_TIME = {100000000,0};	/* For explanation of why 100000000, see ndet_check_tv */static voidndet_update_itimer(enum_itimer)	NDET_ENUM_ITIMER *enum_itimer;{	u_int sigs_tmp;	struct	itimerval process_itimer;	int n;	/* Remember bits of notifier auto signal catcher */	sigs_tmp = ndet_sigs_auto;	/* Zero out polling bit */	ndet_flags &= ~enum_itimer->polling_bit;	ndet_sigs_auto &= ~SIG_BIT(enum_itimer->signal);	/* Recompute interval timer */	enum_itimer->min_tv = NDET_END_OF_TIME;	(void) ntfy_enum_conditions(ndet_clients, ndet_itimer_change,	    (NTFY_ENUM_DATA)enum_itimer);	/* Toggle notifier auto signal catching if situation changed */	ndet_toggle_auto(sigs_tmp, enum_itimer->signal);	/* Set interval timer */	timerclear(&process_itimer.it_interval);	if (ndet_tv_equal(enum_itimer->min_tv, NDET_END_OF_TIME))		/* No one reset min_tv */		timerclear(&enum_itimer->min_tv);	process_itimer.it_value = enum_itimer->min_tv;	n = setitimer(enum_itimer->which, &process_itimer, /* SYSTEM CALL */	    (struct itimerval *)0);	ntfy_assert(n == 0, "Unexpected error: setitimer");}/* * Called to update global polling flags and find global minimum until next * itimer expiration. */static NTFY_ENUMndet_itimer_change(client, condition, context)	NTFY_CLIENT *client;	NTFY_CONDITION *condition;	NTFY_ENUM_DATA context;{	struct timeval local_min;	register NDET_ENUM_ITIMER *enum_itimer = (NDET_ENUM_ITIMER *)context;	register NTFY_ITIMER *n_itimer;	switch (condition->type) {	case NTFY_VIRTUAL_ITIMER:	case NTFY_REAL_ITIMER:		n_itimer = condition->data.ntfy_itimer;		if (condition->type != enum_itimer->type)			break;		/* See if polling itimer */		if (ndet_tv_polling(n_itimer->itimer.it_value))			ndet_flags |= enum_itimer->polling_bit;		else {			/* Figure time to go until expiration for this client */			local_min = enum_itimer->min_func(n_itimer,			    enum_itimer->current_tv);			/* See if expired */			if (!timerisset(&local_min)) {				/*				 * Dispatch notification, reset itimer value,				 * remove if nothing to wait for (returns !0).				 */				ndet_flags |= NDET_ITIMER_ENQ;				if (ndet_itimer_expired(client, condition))					/*					 * Know can skip rest of clients					 * conditions because only one itimer					 * of each type is allowed per client.					 */					return(NTFY_ENUM_SKIP);				/* Else update local_min and set time */				local_min = n_itimer->itimer.it_value;				n_itimer->set_tv = enum_itimer->current_tv;			}			/* Figure global minimum time to go until expiration */			enum_itimer->min_tv = ndet_tv_min(local_min,			    enum_itimer->min_tv);			/*			 * Tell automatic signal mechanism to watch for this			 * kind of interval timer expiration.			 */			ndet_sigs_auto |= SIG_BIT(enum_itimer->signal);		}		/*		 * Know can skip rest of clients conditions because only one		 * itimer of each type is allowed per client.		 */		return(NTFY_ENUM_SKIP);	default: {}	}	return(NTFY_ENUM_NEXT);}/* Update every virtual itimer's set_tv field *//* ARGSUSED */static NTFY_ENUMndet_virtual_set_tv_update(client, condition, context)	NTFY_CLIENT *client;	NTFY_CONDITION *condition;	NTFY_ENUM_DATA context;{	struct timeval *set_tv = (struct timeval *)context;	if (condition->type == NTFY_VIRTUAL_ITIMER) {		condition->data.ntfy_itimer->set_tv = *set_tv;		/*		 * Know can skip rest of clients conditions because only one		 * itimer of each type is allowed per client.		 */		return(NTFY_ENUM_SKIP);	} else		return(NTFY_ENUM_NEXT);}static voidndet_fig_destroy_change(){	u_int sigs_auto_tmp;	ndet_flags &= ~NDET_DESTROY_CHANGE;	/* Remember what signals were catching for auto client */	sigs_auto_tmp = ndet_sigs_auto;	/* Zero out what used to collect the data for auto client */	ndet_sigs_auto &= ~(SIG_BIT(SIGTERM));	/* Recompute SIGTERM managing */	(void) ntfy_enum_conditions(ndet_clients, ndet_destroy_change,	    NTFY_ENUM_DATA_NULL);	/* Toggle notifier auto signal catching if situation changed */	ndet_toggle_auto(sigs_auto_tmp, SIGTERM);}static voidndet_fig_sig_change(){	register u_int sig_bit, sigs_tmp, sigs_dif;	register int sig;	int n;	ndet_flags &= ~NDET_SIGNAL_CHANGE;	/* Remember what signals were catching */	sigs_tmp = ndet_sigs_managing;	/* Zero out what used to collect the data */		/*		 * Note: ndet_signal_catcher shouldn't look at		 * ndet_sigs_managing when NTFY_IN_CRITICAL.		 */	ndet_sigs_managing = 0;	/* Recompute signals managing */	(void) ntfy_enum_conditions(ndet_clients, ndet_sig_change,	    NTFY_ENUM_DATA_NULL);	/* Update signal catching */	sigs_dif = ndet_sigs_managing^sigs_tmp;	for (sig = 1;sig < NSIG;sig++) {		if ((sig_bit = SIG_BIT(sig) & sigs_dif)) {			if (sig_bit & ndet_sigs_managing) {				ndet_enable_sig(sig);			} if (sig_bit & sigs_tmp) {				/*				 * Don't catch this signal,				 * currently we are				 */				n = sigvec(sig, &ndet_prev_sigvec[sig],				    (struct sigvec *)0); /* SYSTEM CALL */				ntfy_assert(n == 0, "Unexpected error: sigvec");			} else				ntfy_set_errno(NOTIFY_INTERNAL_ERROR);		}	}}/* * Call this routine (other than from ndet_fig_sig_change) when you need * to make sure that a signal is being caught but don't want to go through * the whole process of globally finding out who else needs it. */pkg_private voidndet_enable_sig(sig)	int sig;{	if (!(SIG_BIT(sig) & ndet_sigs_managing)) {		int n;		/* Arrange to catch this signal, currently we are not */		n = sigvec(sig, &ndet_sigvec, &ndet_prev_sigvec[sig]);		    /* SYSTEM CALL */		ntfy_assert(n == 0, "Unexpected error: sigvec");		ndet_sigs_managing |= SIG_BIT(sig);	}}pkg_private_data int	ndet_track_sigs = 0;pkg_private void	/* Should be static but there might be clients of it */ndet_signal_catcher(sig, code, scp)	int sig;	int code;	struct sigcontext *scp;{	int oldmask = sigblock((int)ndet_sigs_managing); /* SYSTEM CALL */	void (*old_handler)() = ndet_prev_sigvec[sig].sv_handler;	if (NTFY_IN_CRITICAL || ntfy_nodes_avail < NTFY_PRE_ALLOCED_MIN) {		ntfy_sigs_delayed |= SIG_BIT(sig);		(void) sigsetmask(oldmask); /* SYSTEM CALL */#ifdef	NTFY_DEBUG		if (ndet_track_sigs)		    (void) fprintf(stdout, "SIG caught when CRITICAL %ld\n", sig);#endif	NTFY_DEBUG		goto Done;	}	NTFY_BEGIN_INTERRUPT;	ndet_signal_code = code;	ndet_signal_context = scp;	ndet_send_async_sigs(SIG_BIT(sig));	(void) sigsetmask(oldmask); /* SYSTEM CALL */	NTFY_END_INTERRUPT;Done:	/*	 * Call previous handler.  This feature is not part of the	 * notifier definition but is included as a means of reducing	 * compatibility problems.	 */	if (old_handler != SIG_DFL && old_handler != SIG_IGN)		old_handler(sig, code, scp);#ifdef	NTFY_DEBUG	if (ndet_track_sigs)		(void) fprintf(stdout, "SIG caught %ld\n", sig);#endif	NTFY_DEBUG	return;}pkg_private voidndet_send_delayed_sigs(){	register int sigs;	int oldmask;	ntfy_assert(!NTFY_IN_INTERRUPT, "Tried send delayed sig in interrupt");	ntfy_assert(!NTFY_IN_CRITICAL, "Tried send delayed sig when protected");	/* Don't need to enter critical section because blocking signals. */	/* Carefully reset ntfy_sigs_delayed so don't loose signal. */	oldmask = sigblock((int)ndet_sigs_managing); /* SYSTEM CALL */	sigs = ntfy_sigs_delayed;	ntfy_sigs_delayed = 0;	/* Send delayed signals */	ndet_send_async_sigs(sigs);	(void) sigsetmask(oldmask); /* SYSTEM CALL */}/* Don't need to enter critical section because blocking signals when called. */static voidndet_send_async_sigs(sigs)	int sigs;{	ndet_sigs_received |= sigs;	(void) ntfy_paranoid_enum_conditions(ndet_clients, ndet_async_sig_send,	    (NTFY_ENUM_DATA)sigs);}static NTFY_ENUMndet_async_sig_send(client, condition, context)	NTFY_CLIENT *client;	register NTFY_CONDITION *condition;	NTFY_ENUM_DATA context;{	u_int sigs = (u_int)context;	if (condition->type == NTFY_ASYNC_SIGNAL &&	    (SIG_BIT(condition->data.signal) & sigs)) {		Notify_func func;		/* Push condition on interposition stack */		func = nint_push_callout(client, condition);		/* The notifier doesn't catch any async sigs */		(void) func(client->nclient,		    condition->data.signal, NOTIFY_ASYNC);		/* Pop condition from interposition stack */		nint_unprotected_pop_callout();		/* Note: condition/client may be undefined now! */	}	return(NTFY_ENUM_NEXT);}/* ARGSUSED */static NTFY_ENUMndet_destroy_change(client, condition, context)	NTFY_CLIENT *client;	NTFY_CONDITION *condition;	NTFY_ENUM_DATA context;{	if (condition->type == NTFY_DESTROY)		/* Tell automatic signal mechanism to watch for SIGTERM */		ndet_sigs_auto |= SIG_BIT(SIGTERM);	return(NTFY_ENUM_NEXT);}/* ARGSUSED */static NTFY_ENUMndet_sig_change(client, condition, context)	NTFY_CLIENT *client;	NTFY_CONDITION *condition;	NTFY_ENUM_DATA context;{	if ((condition->type == NTFY_SYNC_SIGNAL) ||	    (condition->type == NTFY_ASYNC_SIGNAL))		ndet_sigs_managing |= SIG_BIT(condition->data.signal);	return(NTFY_ENUM_NEXT);}pkg_private NTFY_ENUMndet_fd_send(client, condition, context)	NTFY_CLIENT *client;	register NTFY_CONDITION *condition;	NTFY_ENUM_DATA context;{	register NDET_ENUM_SEND *enum_send = (NDET_ENUM_SEND *)context;	switch (condition->type) {	case NTFY_INPUT:		if (FD_ISSET(condition->data.fd, &enum_send->ibits))			goto EnQ;		break;	case NTFY_OUTPUT:		if (FD_ISSET(condition->data.fd, &enum_send->obits))			goto EnQ;		break;	case NTFY_EXCEPTION:		if (FD_ISSET(condition->data.fd, &enum_send->ebits))			goto EnQ;		break;	default: {}	}	return(NTFY_ENUM_NEXT);EnQ:	if (ndis_enqueue(client, condition) != NOTIFY_OK)		/* Internal fatal error */		return(NTFY_ENUM_TERM);	return(NTFY_ENUM_NEXT);}static NTFY_ENUMndet_sig_send(client, condition, context)	NTFY_CLIENT *client;	register NTFY_CONDITION *condition;	NTFY_ENUM_DATA context;{	register NDET_ENUM_SEND *enum_send = (NDET_ENUM_SEND *)context;	if (condition->type == NTFY_SYNC_SIGNAL &&	    (SIG_BIT(condition->data.signal) & enum_send->sigs)) {		/* Intercept conditions that were set by the notifier */		if (client->nclient == ndet_auto_nclient)			return(ndet_auto_sig_send(client, condition, context));		else {			if (ndis_enqueue(client, condition) != NOTIFY_OK)				ntfy_fatal_error("Error when enq condition");		}	}	return(NTFY_ENUM_NEXT);}/* ARGSUSED */static NTFY_ENUMndet_poll_send(client, condition, context)	NTFY_CLIENT *client;	register NTFY_CONDITION *condition;	NTFY_ENUM_DATA context;{	if ((condition->type == NTFY_REAL_ITIMER ||	    condition->type == NTFY_VIRTUAL_ITIMER) &&	    ndet_tv_polling(condition->data.ntfy_itimer->itimer.it_value)) {		/*		 * Dispatch notification, reset itimer value,		 * remove if nothing to wait for an return -1 else 0.		 */		if (!ndet_itimer_expired(client, condition)) {			/*			 * Avoid making system call in ndet_reset_itimer_set_tv			 * if just only to be polling again.			 */			if (!ndet_tv_polling(			    condition->data.ntfy_itimer->itimer.it_value))				ndet_reset_itimer_set_tv(condition);		}		/*		 * Know can skip rest of clients conditions because		 * only one itimer of each type is allowed per client.		 */		return(NTFY_ENUM_SKIP);	}	return(NTFY_ENUM_NEXT);}extern voidnotify_set_signal_check(tv)	struct timeval tv;{	ndet_signal_check = tv;}extern struct timevalnotify_get_signal_check(){	return (ndet_signal_check);}extern intnotify_get_signal_code(){	/* Could put check to see if in interrupt (should be) */	return (ndet_signal_code);}extern struct sigcontext *notify_get_signal_context(){	/* Could put check to see if in interrupt (should be) */	return (ndet_signal_context);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -