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

📄 ndis_dispatch.c

📁 操作系统SunOS 4.1.3版本的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
#ifndef	lint#ifdef sccsstatic	char sccsid[] = "@(#)ndis_dispatch.c 1.1 92/07/30 Copyr 1985 Sun Micro";#endif#endif /* * Copyright (c) 1985 by Sun Microsystems, Inc. *//* * Ndis_dispatch.c - Central control mechanism for the dispatcher. */#include <sunwindow/ntfy.h>#include <sunwindow/ndis.h>#include <sunwindow/nint.h>#include <sunwindow/ndet.h>	/* For ndet_set_event_processing/ndet_flags */#include <signal.h>/* performance: global cache of getdtablesize() */extern int dtablesize_cache;#define GETDTABLESIZE() \	(dtablesize_cache?dtablesize_cache:(dtablesize_cache=getdtablesize()))pkg_private_data u_int	ndis_flags = 0;pkg_private_data NTFY_CLIENT *ndis_clients = 0;pkg_private_data NTFY_CLIENT *ndis_client_latest = 0;pkg_private_data Notify_value (*ndis_scheduler)() = ndis_default_scheduler;static	Notify_client *ndis_sched_nclients;/* Parallel data structure to					   ndis_clients for use with scheduler*/static	u_int ndis_sched_count;		/* Last valid position (plus one) in					   ndis_sched_nclients */static	u_int ndis_sched_length;	/* Current length of					   ndis_sched_nclients */static	Notify_event *ndis_events;	/* List of events currently being					   dispatched for a given client */static	Notify_arg *ndis_args;		/* List of event args currently being					   dispatched for a given client					   (parallels ndis_events) */static	u_int ndis_event_count;		/* Last valid position (plus one) in					   ndis_events & ndis_args */static	u_int ndis_event_length;	/* Current length of ndis_events &					   ndis_args */static	Notify_error ndis_send_func();	/* Used to get func for sending notify*/#define	NDIS_RELEASE_NULL	((Notify_release *)0)static	NTFY_ENUM ndis_setup_sched_clients();/* Enqueue condition from dectector on to the dispatchers client list */pkg_private Notify_errorndis_enqueue(ndet_client, ndet_condition)	register NTFY_CLIENT *ndet_client;	register NTFY_CONDITION *ndet_condition;{	register NTFY_CLIENT *client;	register NTFY_CONDITION *condition;	ntfy_assert(NTFY_IN_CRITICAL, "Not protected when enqueue condition");	/* Find/create client that corresponds to ndet_client */	if ((client = ntfy_new_nclient(&ndis_clients, ndet_client->nclient,            &ndis_client_latest)) == NTFY_CLIENT_NULL)		goto Error;	client->prioritizer = ndet_client->prioritizer;	/* Allocate condition */	if ((condition = ntfy_alloc_condition()) == NTFY_CONDITION_NULL)		goto Error;	/* Initialize condition */	condition->next = NTFY_CONDITION_NULL;	condition->type = ndet_condition->type;	condition->release = ndet_condition->release;	condition->arg = ndet_condition->arg;	switch (condition->type) {	case NTFY_REAL_ITIMER:	case NTFY_VIRTUAL_ITIMER:		condition->data.an_u_int = 0;		break;	case NTFY_WAIT3:		if ((condition->data.wait3 = (NTFY_WAIT3_DATA *) ntfy_malloc(		    sizeof(NTFY_WAIT3_DATA))) == NTFY_WAIT3_DATA_NULL)			goto Error;		*condition->data.wait3 = *ndet_condition->data.wait3;		break;	default:		condition->data.an_u_int = ndet_condition->data.an_u_int;		break;	}	condition->func_count = ndet_condition->func_count;	condition->func_next = 0;	if (nint_copy_callout(condition, ndet_condition) != NOTIFY_OK)		goto Error;	/* Append to condition list */	ntfy_append_condition(&(client->conditions), condition);	/* Set up condition hint */	client->condition_latest = condition;	/* Set dispatcher flag */	ndis_flags |= NDIS_EVENT_QUEUED;	return(NOTIFY_OK);Error:	return(notify_errno);}/* Dispatch to all clients according to the scheduler */pkg_private Notify_errorndis_dispatch(){	Notify_value (*sched_func)();	/* Quick bailout if nothing to send */	if (ndis_clients == NTFY_CLIENT_NULL)		return(NOTIFY_OK);	ntfy_assert(!NTFY_IN_CRITICAL, "In critical when dispatch");	ntfy_assert(!NTFY_IN_INTERRUPT, "In interrupt when dispatch");	NTFY_BEGIN_CRITICAL;	/* Build nclient list for scheduler */	for (;;) {		ndis_sched_count = 0;		/* If enumerator returns NTFY_ENUM_TERM then list too short */		if (ntfy_enum_conditions(ndis_clients, ndis_setup_sched_clients,		     NTFY_ENUM_DATA_NULL) == NTFY_ENUM_TERM) {			/* Free previous list */			if (ndis_sched_nclients)				ntfy_free_malloc(				    (NTFY_DATA)ndis_sched_nclients);			/* Allocate new list */			ndis_sched_length += 20;			if ((ndis_sched_nclients = (Notify_client *)			  ntfy_malloc(ndis_sched_length*sizeof(Notify_client)))			  == (Notify_client *)0) {				NTFY_END_CRITICAL;				return(notify_errno);			}		} else			break;	}	/* Call scheduler */	sched_func = ndis_scheduler;	NTFY_END_CRITICAL;	if (sched_func(ndis_sched_count, ndis_sched_nclients) ==	    NOTIFY_UNEXPECTED)		/*		 * Scheduler sets notify_errno and returns error if there		 * is some non-callout related problem.		 */		return(notify_errno);	return(NOTIFY_OK);}/* ARGSUSED */static NTFY_ENUMndis_setup_sched_clients(client, condition, context)	NTFY_CLIENT *client;	NTFY_CONDITION *condition;	NTFY_ENUM_DATA context;{	/* Terminate enumeration if next slot overflows size of client table */	if (ndis_sched_count == ndis_sched_length)		return(NTFY_ENUM_TERM);	*(ndis_sched_nclients+ndis_sched_count) = client->nclient;	ndis_sched_count++;	return(NTFY_ENUM_SKIP);}/* Flush given nclient & its conditions */extern voidnotify_flush_pending(nclient)	Notify_client nclient;{	NTFY_CLIENT *client;	register int i;	NTFY_BEGIN_CRITICAL;	if ((client = ntfy_find_nclient(ndis_clients, nclient,            &ndis_client_latest)) == NTFY_CLIENT_NULL)		goto Done;	else {		/* Flush any pending notification from dispatcher */		ntfy_remove_client(&ndis_clients, client, &ndis_client_latest,		    NTFY_NDIS);		/* Remove nclient from list of clients to be scheduled */		for (i = 0; i < ndis_sched_length; i++)			if (ndis_sched_nclients[i] == nclient)				ndis_sched_nclients[i] = NOTIFY_CLIENT_NULL;		/*		 * The dispatcher may be calling out to an nclient at this time.		 * When an nclient calls back in, we always check the validity		 * of the handle.  Thus, the dispatcher ignores any further		 * references to client.		 */	}Done:	NTFY_END_CRITICAL;	return;}extern Notify_errornotify_client(nclient)	Notify_client nclient;{	NTFY_CLIENT *client;	register NTFY_CONDITION *cdn;	int sigbits, auto_sigbits;	fd_set ibits, obits, ebits;	    /* Don't make register because take address of them */	Notify_value (*pri_func)();	int maxfds	= GETDTABLESIZE();	/* Check if heap access protected */	ntfy_assert(!NTFY_IN_INTERRUPT, "In interrupt when notify");	NTFY_BEGIN_CRITICAL;Retry_Client:	/* Find client */	if ((client = ntfy_find_nclient(ndis_clients, nclient,	    &ndis_client_latest)) == NTFY_CLIENT_NULL)		/* Can get here on first time if client removed pending cond */		goto Done;	/* Reset flags that detects when another condition enqueued */	ndis_flags &= ~NDIS_EVENT_QUEUED;Retry_Conditions:	/* Initialize prioritizer arguments */	sigbits = auto_sigbits = 0;	FD_ZERO(&ibits); FD_ZERO(&obits);  FD_ZERO(&ebits);	ndis_event_count = 0;	/* Fill out prioritizer arguments based on conditions */	for (cdn = client->conditions; cdn; cdn = cdn->next) {		switch (cdn->type) {		case NTFY_INPUT:			FD_SET(cdn->data.fd, &ibits);			break;		case NTFY_OUTPUT:			FD_SET(cdn->data.fd, &obits);			break;		case NTFY_EXCEPTION:			FD_SET(cdn->data.fd, &ebits);			break;		case NTFY_SYNC_SIGNAL:			sigbits |= SIG_BIT(cdn->data.signal);			break;		case NTFY_REAL_ITIMER:			auto_sigbits |= SIG_BIT(SIGALRM);			break;		case NTFY_VIRTUAL_ITIMER:			auto_sigbits |= SIG_BIT(SIGVTALRM);			break;		case NTFY_WAIT3:			auto_sigbits |= SIG_BIT(SIGCHLD);			break;		case NTFY_DESTROY:			switch (cdn->data.status) {			case DESTROY_CLEANUP:				auto_sigbits |= SIG_BIT(SIGTERM);				break;			case DESTROY_PROCESS_DEATH:				auto_sigbits |= SIG_BIT(SIGKILL);				break;			case DESTROY_CHECKING:				auto_sigbits |= SIG_BIT(SIGTSTP);				break;			}			break;		case NTFY_SAFE_EVENT:			/*			 * Build event list for prioritizer.			 * Terminate condition traversal if next slot			 * overflows size of event table.			 */			if (ndis_event_count == ndis_event_length) {				/* Free previous list */				if (ndis_events) {					ntfy_free_malloc(					    (NTFY_DATA)ndis_events);					ntfy_free_malloc(					    (NTFY_DATA)ndis_args);				}				/* Allocate new list */				ndis_event_length += 20;				if ((ndis_events = (Notify_event *)				    ntfy_malloc(ndis_event_length*				    sizeof(Notify_event))) == (Notify_event *)0)					goto Error;				if ((ndis_args = (Notify_arg *)				    ntfy_malloc(ndis_event_length*				    sizeof(Notify_arg))) == (Notify_arg *)0)					goto Error;				/* Restart condition traversal */				goto Retry_Conditions;			}			*(ndis_events+ndis_event_count) = cdn->data.event;			*(ndis_args+ndis_event_count) = cdn->arg;			ndis_event_count++;			break;		default:			ntfy_fatal_error("Unexpected dispatcher cond");		}	}	/* Call prioritizer */	pri_func = client->prioritizer;	NTFY_END_CRITICAL;/* the second arg to pri_func should be max fd # for select call ??? */	(void) pri_func(nclient, maxfds, &ibits, &obits, &ebits,	    NSIG, &sigbits, &auto_sigbits, &ndis_event_count, ndis_events,	    ndis_args);

⌨️ 快捷键说明

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