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

📄 tclio.c

📁 linux系统下的音频通信
💻 C
📖 第 1 页 / 共 5 页
字号:
    chanPtr->scriptRecordPtr = (EventScriptRecord *) NULL;    chanPtr->bufSize = CHANNELBUFFER_DEFAULT_SIZE;    chanPtr->timer = NULL;    chanPtr->csPtr = NULL;    /*     * Link the channel into the list of all channels; create an on-exit     * handler if there is not one already, to close off all the channels     * in the list on exit.     */    chanPtr->nextChanPtr = firstChanPtr;    firstChanPtr = chanPtr;    if (!channelExitHandlerCreated) {        channelExitHandlerCreated = 1;        Tcl_CreateExitHandler(CloseChannelsOnExit, (ClientData) NULL);    }        /*     * Install this channel in the first empty standard channel slot, if     * the channel was previously closed explicitly.     */    if ((stdinChannel == NULL) && (stdinInitialized == 1)) {	Tcl_SetStdChannel((Tcl_Channel)chanPtr, TCL_STDIN);        Tcl_RegisterChannel((Tcl_Interp *) NULL, (Tcl_Channel) chanPtr);    } else if ((stdoutChannel == NULL) && (stdoutInitialized == 1)) {	Tcl_SetStdChannel((Tcl_Channel)chanPtr, TCL_STDOUT);        Tcl_RegisterChannel((Tcl_Interp *) NULL, (Tcl_Channel) chanPtr);    } else if ((stderrChannel == NULL) && (stderrInitialized == 1)) {	Tcl_SetStdChannel((Tcl_Channel)chanPtr, TCL_STDERR);        Tcl_RegisterChannel((Tcl_Interp *) NULL, (Tcl_Channel) chanPtr);    }     return (Tcl_Channel) chanPtr;}/* *---------------------------------------------------------------------- * * Tcl_GetChannelMode -- * *	Computes a mask indicating whether the channel is open for *	reading and writing. * * Results: *	An OR-ed combination of TCL_READABLE and TCL_WRITABLE. * * Side effects: *	None. * *---------------------------------------------------------------------- */intTcl_GetChannelMode(chan)    Tcl_Channel chan;		/* The channel for which the mode is                                 * being computed. */{    Channel *chanPtr;		/* The actual channel. */    chanPtr = (Channel *) chan;    return (chanPtr->flags & (TCL_READABLE | TCL_WRITABLE));}/* *---------------------------------------------------------------------- * * Tcl_GetChannelName -- * *	Returns the string identifying the channel name. * * Results: *	The string containing the channel name. This memory is *	owned by the generic layer and should not be modified by *	the caller. * * Side effects: *	None. * *---------------------------------------------------------------------- */char *Tcl_GetChannelName(chan)    Tcl_Channel chan;		/* The channel for which to return the name. */{    Channel *chanPtr;		/* The actual channel. */    chanPtr = (Channel *) chan;    return chanPtr->channelName;}/* *---------------------------------------------------------------------- * * Tcl_GetChannelType -- * *	Given a channel structure, returns the channel type structure. * * Results: *	Returns a pointer to the channel type structure. * * Side effects: *	None. * *---------------------------------------------------------------------- */Tcl_ChannelType *Tcl_GetChannelType(chan)    Tcl_Channel chan;		/* The channel to return type for. */{    Channel *chanPtr;		/* The actual channel. */    chanPtr = (Channel *) chan;    return chanPtr->typePtr;}/* *---------------------------------------------------------------------- * * Tcl_GetChannelHandle -- * *	Returns an OS handle associated with a channel. * * Results: *	Returns TCL_OK and places the handle in handlePtr, or returns *	TCL_ERROR on failure. * * Side effects: *	None. * *---------------------------------------------------------------------- */intTcl_GetChannelHandle(chan, direction, handlePtr)    Tcl_Channel chan;		/* The channel to get file from. */    int direction;		/* TCL_WRITABLE or TCL_READABLE. */    ClientData *handlePtr;	/* Where to store handle */{    Channel *chanPtr;		/* The actual channel. */    ClientData handle;    int result;    chanPtr = (Channel *) chan;    result = (chanPtr->typePtr->getHandleProc)(chanPtr->instanceData,	    direction, &handle);    if (handlePtr) {	*handlePtr = handle;    }    return result;}/* *---------------------------------------------------------------------- * * Tcl_GetChannelInstanceData -- * *	Returns the client data associated with a channel. * * Results: *	The client data. * * Side effects: *	None. * *---------------------------------------------------------------------- */ClientDataTcl_GetChannelInstanceData(chan)    Tcl_Channel chan;		/* Channel for which to return client data. */{    Channel *chanPtr;		/* The actual channel. */    chanPtr = (Channel *) chan;    return chanPtr->instanceData;}/* *---------------------------------------------------------------------- * * RecycleBuffer -- * *	Helper function to recycle input and output buffers. Ensures *	that two input buffers are saved (one in the input queue and *	another in the saveInBufPtr field) and that curOutPtr is set *	to a buffer. Only if these conditions are met is the buffer *	freed to the OS. * * Results: *	None. * * Side effects: *	May free a buffer to the OS. * *---------------------------------------------------------------------- */static voidRecycleBuffer(chanPtr, bufPtr, mustDiscard)    Channel *chanPtr;		/* Channel for which to recycle buffers. */    ChannelBuffer *bufPtr;	/* The buffer to recycle. */    int mustDiscard;		/* If nonzero, free the buffer to the                                 * OS, always. */{    /*     * Do we have to free the buffer to the OS?     */    if (mustDiscard) {        ckfree((char *) bufPtr);        return;    }        /*     * Only save buffers for the input queue if the channel is readable.     */        if (chanPtr->flags & TCL_READABLE) {        if (chanPtr->inQueueHead == (ChannelBuffer *) NULL) {            chanPtr->inQueueHead = bufPtr;            chanPtr->inQueueTail = bufPtr;            goto keepit;        }        if (chanPtr->saveInBufPtr == (ChannelBuffer *) NULL) {            chanPtr->saveInBufPtr = bufPtr;            goto keepit;        }    }    /*     * Only save buffers for the output queue if the channel is writable.     */    if (chanPtr->flags & TCL_WRITABLE) {        if (chanPtr->curOutPtr == (ChannelBuffer *) NULL) {            chanPtr->curOutPtr = bufPtr;            goto keepit;        }    }    /*     * If we reached this code we return the buffer to the OS.     */    ckfree((char *) bufPtr);    return;keepit:    bufPtr->nextRemoved = 0;    bufPtr->nextAdded = 0;    bufPtr->nextPtr = (ChannelBuffer *) NULL;}/* *---------------------------------------------------------------------- * * DiscardOutputQueued -- * *	Discards all output queued in the output queue of a channel. * * Results: *	None. * * Side effects: *	Recycles buffers. * *---------------------------------------------------------------------- */static voidDiscardOutputQueued(chanPtr)    Channel *chanPtr;		/* The channel for which to discard output. */{    ChannelBuffer *bufPtr;        while (chanPtr->outQueueHead != (ChannelBuffer *) NULL) {        bufPtr = chanPtr->outQueueHead;        chanPtr->outQueueHead = bufPtr->nextPtr;        RecycleBuffer(chanPtr, bufPtr, 0);    }    chanPtr->outQueueHead = (ChannelBuffer *) NULL;    chanPtr->outQueueTail = (ChannelBuffer *) NULL;}/* *---------------------------------------------------------------------- * * CheckForDeadChannel -- * *	This function checks is a given channel is Dead. *      (A channel that has been closed but not yet deallocated.) * * Results: *	True (1) if channel is Dead, False (0) if channel is Ok * * Side effects: *      None * *---------------------------------------------------------------------- */static intCheckForDeadChannel(interp, chanPtr)    Tcl_Interp *interp;		/* For error reporting (can be NULL) */    Channel    *chanPtr;	/* The channel to check. */{    if (chanPtr->flags & CHANNEL_DEAD) {        Tcl_SetErrno(EINVAL);	if (interp) {	    Tcl_AppendResult(interp,			     "unable to access channel: invalid channel",			     (char *) NULL);   	}	return 1;    }    return 0;}/* *---------------------------------------------------------------------- * * FlushChannel -- * *	This function flushes as much of the queued output as is possible *	now. If calledFromAsyncFlush is nonzero, it is being called in an *	event handler to flush channel output asynchronously. * * Results: *	0 if successful, else the error code that was returned by the *	channel type operation. * * Side effects: *	May produce output on a channel. May block indefinitely if the *	channel is synchronous. May schedule an async flush on the channel. *	May recycle memory for buffers in the output queue. * *---------------------------------------------------------------------- */static intFlushChannel(interp, chanPtr, calledFromAsyncFlush)    Tcl_Interp *interp;			/* For error reporting during close. */    Channel *chanPtr;			/* The channel to flush on. */    int calledFromAsyncFlush;		/* If nonzero then we are being                                         * called from an asynchronous                                         * flush callback. */{    ChannelBuffer *bufPtr;		/* Iterates over buffered output                                         * queue. */    int toWrite;			/* Amount of output data in current                                         * buffer available to be written. */    int written;			/* Amount of output data actually                                         * written in current round. */    int errorCode;			/* Stores POSIX error codes from                                         * channel driver operations. */    errorCode = 0;    /*     * Prevent writing on a dead channel -- a channel that has been closed     * but not yet deallocated. This can occur if the exit handler for the     * channel deallocation runs before all channels are deregistered in     * all interpreters.     */        if (CheckForDeadChannel(interp,chanPtr)) return -1;        /*     * Loop over the queued buffers and attempt to flush as     * much as possible of the queued output to the channel.     */    while (1) {        /*         * If the queue is empty and there is a ready current buffer, OR if         * the current buffer is full, then move the current buffer to the         * queue.         */                if (((chanPtr->curOutPtr != (ChannelBuffer *) NULL) &&                (chanPtr->curOutPtr->nextAdded == chanPtr->curOutPtr->bufSize))                || ((chanPtr->flags & BUFFER_READY) &&                        (chanPtr->outQueueHead == (ChannelBuffer *) NULL))) {            chanPtr->flags &= (~(BUFFER_READY));            chanPtr->curOutPtr->nextPtr = (ChannelBuffer *) NULL;            if (chanPtr->outQueueHead == (ChannelBuffer *) NULL) {                chanPtr->outQueueHead = chanPtr->curOutPtr;            } else {                chanPtr->outQueueTail->nextPtr = chanPtr->curOutPtr;            }            chanPtr->outQueueTail = chanPtr->curOutPtr;            chanPtr->curOutPtr = (ChannelBuffer *) NULL;        }        bufPtr = chanPtr->outQueueHead;        /*         * If we are not being called from an async flush and an async         * flush is active, we just return without producing any output.         */        if ((!calledFromAsyncFlush) &&

⌨️ 快捷键说明

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