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

📄 tclasync.c

📁 linux系统下的音频通信
💻 C
字号:
/*  * tclAsync.c -- * *	This file provides low-level support needed to invoke signal *	handlers in a safe way.  The code here doesn't actually handle *	signals, though.  This code is based on proposals made by *	Mark Diekhans and Don Libes. * * Copyright (c) 1993 The Regents of the University of California. * Copyright (c) 1994 Sun Microsystems, Inc. * * See the file "license.terms" for information on usage and redistribution * of this file, and for a DISCLAIMER OF ALL WARRANTIES. * * SCCS: @(#) tclAsync.c 1.6 96/02/15 11:46:15 */#include "tclInt.h"/* * One of the following structures exists for each asynchronous * handler: */typedef struct AsyncHandler {    int ready;				/* Non-zero means this handler should					 * be invoked in the next call to					 * Tcl_AsyncInvoke. */    struct AsyncHandler *nextPtr;	/* Next in list of all handlers for					 * the process. */    Tcl_AsyncProc *proc;		/* Procedure to call when handler					 * is invoked. */    ClientData clientData;		/* Value to pass to handler when it					 * is invoked. */} AsyncHandler;/* * The variables below maintain a list of all existing handlers. */static AsyncHandler *firstHandler;	/* First handler defined for process,					 * or NULL if none. */static AsyncHandler *lastHandler;	/* Last handler or NULL. *//* * The variable below is set to 1 whenever a handler becomes ready and * it is cleared to zero whenever Tcl_AsyncInvoke is called.  It can be * checked elsewhere in the application by calling Tcl_AsyncReady to see * if Tcl_AsyncInvoke should be invoked. */static int asyncReady = 0;/* * The variable below indicates whether Tcl_AsyncInvoke is currently * working.  If so then we won't set asyncReady again until * Tcl_AsyncInvoke returns. */static int asyncActive = 0;/* *---------------------------------------------------------------------- * * Tcl_AsyncCreate -- * *	This procedure creates the data structures for an asynchronous *	handler, so that no memory has to be allocated when the handler *	is activated. * * Results: *	The return value is a token for the handler, which can be used *	to activate it later on. * * Side effects: *	Information about the handler is recorded. * *---------------------------------------------------------------------- */Tcl_AsyncHandlerTcl_AsyncCreate(proc, clientData)    Tcl_AsyncProc *proc;		/* Procedure to call when handler					 * is invoked. */    ClientData clientData;		/* Argument to pass to handler. */{    AsyncHandler *asyncPtr;    asyncPtr = (AsyncHandler *) ckalloc(sizeof(AsyncHandler));    asyncPtr->ready = 0;    asyncPtr->nextPtr = NULL;    asyncPtr->proc = proc;    asyncPtr->clientData = clientData;    if (firstHandler == NULL) {	firstHandler = asyncPtr;    } else {	lastHandler->nextPtr = asyncPtr;    }    lastHandler = asyncPtr;    return (Tcl_AsyncHandler) asyncPtr;}/* *---------------------------------------------------------------------- * * Tcl_AsyncMark -- * *	This procedure is called to request that an asynchronous handler *	be invoked as soon as possible.  It's typically called from *	an interrupt handler, where it isn't safe to do anything that *	depends on or modifies application state. * * Results: *	None. * * Side effects: *	The handler gets marked for invocation later. * *---------------------------------------------------------------------- */voidTcl_AsyncMark(async)    Tcl_AsyncHandler async;		/* Token for handler. */{    ((AsyncHandler *) async)->ready = 1;    if (!asyncActive) {	asyncReady = 1;    }}/* *---------------------------------------------------------------------- * * Tcl_AsyncInvoke -- * *	This procedure is called at a "safe" time at background level *	to invoke any active asynchronous handlers. * * Results: *	The return value is a normal Tcl result, which is intended to *	replace the code argument as the current completion code for *	interp. * * Side effects: *	Depends on the handlers that are active. * *---------------------------------------------------------------------- */intTcl_AsyncInvoke(interp, code)    Tcl_Interp *interp;			/* If invoked from Tcl_Eval just after					 * completing a command, points to					 * interpreter.  Otherwise it is					 * NULL. */    int code; 				/* If interp is non-NULL, this gives					 * completion code from command that					 * just completed. */{    AsyncHandler *asyncPtr;    if (asyncReady == 0) {	return code;    }    asyncReady = 0;    asyncActive = 1;    if (interp == NULL) {	code = 0;    }    /*     * Make one or more passes over the list of handlers, invoking     * at most one handler in each pass.  After invoking a handler,     * go back to the start of the list again so that (a) if a new     * higher-priority handler gets marked while executing a lower     * priority handler, we execute the higher-priority handler     * next, and (b) if a handler gets deleted during the execution     * of a handler, then the list structure may change so it isn't     * safe to continue down the list anyway.     */    while (1) {	for (asyncPtr = firstHandler; asyncPtr != NULL;		asyncPtr = asyncPtr->nextPtr) {	    if (asyncPtr->ready) {		break;	    }	}	if (asyncPtr == NULL) {	    break;	}	asyncPtr->ready = 0;	code = (*asyncPtr->proc)(asyncPtr->clientData, interp, code);    }    asyncActive = 0;    return code;}/* *---------------------------------------------------------------------- * * Tcl_AsyncDelete -- * *	Frees up all the state for an asynchronous handler.  The handler *	should never be used again. * * Results: *	None. * * Side effects: *	The state associated with the handler is deleted. * *---------------------------------------------------------------------- */voidTcl_AsyncDelete(async)    Tcl_AsyncHandler async;		/* Token for handler to delete. */{    AsyncHandler *asyncPtr = (AsyncHandler *) async;    AsyncHandler *prevPtr;    if (firstHandler == asyncPtr) {	firstHandler = asyncPtr->nextPtr;	if (firstHandler == NULL) {	    lastHandler = NULL;	}    } else {	prevPtr = firstHandler;	while (prevPtr->nextPtr != asyncPtr) {	    prevPtr = prevPtr->nextPtr;	}	prevPtr->nextPtr = asyncPtr->nextPtr;	if (lastHandler == asyncPtr) {	    lastHandler = prevPtr;	}    }    ckfree((char *) asyncPtr);}/* *---------------------------------------------------------------------- * * Tcl_AsyncReady -- * *	This procedure can be used to tell whether Tcl_AsyncInvoke *	needs to be called.  This procedure is the external interface *	for checking the internal asyncReady variable. * * Results: * 	The return value is 1 whenever a handler is ready and is 0 *	when no handlers are ready. * * Side effects: *	None. * *---------------------------------------------------------------------- */intTcl_AsyncReady(){    return asyncReady;}

⌨️ 快捷键说明

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