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

📄 wvlib.c

📁 vxworks5.5.1源代码。完整源代码
💻 C
📖 第 1 页 / 共 5 页
字号:
* Setting exitWhenEmpty to false is used to continuously upload events as* they are logged to the buffer.  The semaphore uploadCompleteSem, also* contained in the WV_UPLOADTASK_ID, is given when the this routine has* emptied the buffer.  This allows others to wait until the buffer is* empty.** If an error occurs when reading from the buffers or writing to the upload* path, event logging is stopped and the upload path is closed.  The status* field in the WV_UPLOADTASK_ID indicates whether the upload was successful* or if an error occurred.  When writing to the upload path, if an EAGAIN* or EWOULDBLOCK error is encountered due to a failure to write to a non-* blocking path, this routine will backoff and retry to write to the path.* The number of times to attempt writing, and the the amount of time to* delay between attempts can be set with the global variables** 	int wvUploadMaxAttempts		-- 200 by default* 	int wvUploadRetryBackoff 	-- 6 by default (in ticks)** If the block of data, usually one threshold in size, can not be written* within the maximum number of attempts, this routine will stop event * logging, close the upload path and indicate the error within the status* field of the WV_UPLOADTASK_ID.** To avoid copying the event data to a local buffer, only to be copied again* to the upload path, reading the buffer is done using a reserve/commit* interface.  Reserving a number of bytes to read from the buffer provides* access, via a pointer, directly to the event data in the buffer.  This* pointer references only contiguous memory and can be passed directly to the* upload mechanism.  Hence no extra copying is employed.  The buffer's* commit interface is used to notify the buffering mechanism that the* reserved memory has been consumed.** The semaphore on which wvUpload blocks works together with the threshold,* also part of the BUFFER_ID, as a general purpose mechanism for telling* users of the buffer when threshold bytes of data are contained in the* buffer.  This gives the the uploader a way of controlling the frequency * and size of uploads.  The threshold is assigned by the buffer mechanism,* but can be an arbitrary value.  In general, the buffer may assign threshold* to meet a buffer contraint, or it may allow the user to assign it, and * allow access to its value in the structure pointed to by the BUFFER_ID.** All buffer accesses are protected with interrupts locked out.** RETURNS: OK when buffer is successfully emptied and uploaded and*          the upload task ID's exitWhenEmpty is set to TRUE.*          ERROR if an error occurs with the upload path or buffers; event*          logging is stopped if an error occurs.** SEE ALSO:* NOMANUAL**/static STATUS wvUpload     (    WV_UPLOADTASK_ID    upTaskId	/* this task's descriptor */    )    {    int       nReserved;	/* num bytes reserved and possible to upload */    int       nToWrite;		/* num bytes that should be written to host */    int       nUploaded;	/* number of bytes actually written to host */    int       nToCommit;	/* number of bytes to commit in the buffer */    int	      tmp;		/* temporary used to count uploaded bytes */    BOOL      bufferEmpty; 	/* used to exit when buffer is empty */    UINT8     *pData;		/* pointer to the read-reserved data */    int       lockKey;		/* for interrupt locking */    BUFFER_ID bufId;		/* convenient access to upTaskId->bufferId */    UPLOAD_ID pathId;		/* same for upTaskId->uploadPathId */    /* Check that the upload-task id has appropriate information. */    if (upTaskId == NULL)	return (ERROR);    if (upTaskId->bufferId == NULL)	{	upTaskId->status = ERROR;	return (ERROR);	}    if (upTaskId->uploadPathId == NULL)	{	upTaskId->status = ERROR;	return (ERROR);	}    /* Initialize variables. */    bufId   = upTaskId->bufferId;    pathId  = upTaskId->uploadPathId;    bufferEmpty = FALSE;    nToWrite    = 0;    while (TRUE)        {        /* 	 * Initialize variables that allow us to stop uploading at the right	 * time.  Assuming that there is data in the buffer (bufferEmtpy =	 * FALSE) is alright because nothing below will error if there is	 * not.  In other words, bufferEmpty accurately describes when the	 * buffer is empty but does not accurately describe when the buffer	 * is not empty.	 */        nUploaded = 0;	bufferEmpty = FALSE;	/* 	 * If the caller requested to exit when the buffer is empty, give	 * him/er the result immediately, even if there is no data available.	 * Also, if there is still more than a threshold of data in the buffer,	 * continue uploading.  Otherwise block until sufficient data becomes	 * available.	 */        lockKey = intLock ();	tmp = bufId->nBytesRtn (bufId);	intUnlock (lockKey);        if (! upTaskId->exitWhenEmpty && (tmp < bufId->threshold))	    semTake (& bufId->threshXSem, WAIT_FOREVER);	/*	 * Upload in chunks of size bufId->threshold.  The readReserve	 * routine of the buffer only guarantees that every time the	 * threshXSem is able to be taken there are threshold bytes of data	 * in the buffer.  That data may not be contiguous, and so we have	 * to loop until threshold bytes have been uploaded.         */                while ((nUploaded < bufId->threshold) && !bufferEmpty)	    {	                 /* Reserve as many contiguous bytes as possible from the buffer. */	    lockKey = intLock ();            nReserved = bufId->readReserveRtn (bufId, &pData);	    intUnlock (lockKey);            if (nReserved == ERROR)	        {	        /* 	         * If an error occurs close the upload path and stop event		 * logging.  There is no harm in turning event logging off		 * if it is not currently on.	         */                lockKey = intLock ();		wvEvtLogStop();		intUnlock (lockKey);		pathId->errorRtn (pathId);	        upTaskId->status = ERROR;		logMsg ("tWvUpload: failed to read from buffer.\n", 			0, 0, 0, 0, 0, 0);		return (ERROR);                }            /* Notice when the buffer is emptied. */            if (nReserved == 0)		bufferEmpty = TRUE;            else		bufferEmpty = FALSE; 	    /* 	     * Write as many bytes as possible that still need to be uploaed,	     * to the host, but not more than threshold.  And, remember how 	     * many to commit later.	     */            nToWrite = (nReserved > (bufId->threshold - nUploaded)) ? 		       (bufId->threshold - nUploaded) : nReserved;            nToCommit = nToWrite;            if (uploadPathWrite (pathId, pData, nToWrite) == ERROR)                {                /*                 * There is still no harm in turning off event logging                 * if it is not currently on.                 */                lockKey = intLock ();                wvEvtLogStop();                intUnlock (lockKey);                pathId->errorRtn (pathId);                upTaskId->status = ERROR;                logMsg ("tWVUpload: failed writing to host.\n",                        0, 0, 0, 0, 0, 0);                return (ERROR);                }            /* 	     * At this point all the reserved bytes that were possible to 	     * read in this pass through the loop have been uploaded.  Those	     * bytes are committed before determining whether to loop again.	     */            lockKey = intLock ();            tmp = bufId->readCommitRtn (bufId, nToCommit);	    intUnlock (lockKey);             if (tmp == ERROR)		{		/* 		 * There is no harm in turning logging off if it is already 		 * off.		 */                lockKey = intLock ();		wvEvtLogStop();		intUnlock (lockKey);		pathId->errorRtn (pathId);	        upTaskId->status = ERROR;		logMsg ("tWvUpload: failed to commit uploaded bytes.\n", 			0, 0, 0, 0, 0, 0);		return (ERROR);                }            nUploaded += nToCommit;	    }            /* 	     * At this point the buffer is empty or threshold bytes have been	     * uploaded.  Exit only if the buffer was emptied and the user 	     * requested not to wait for more data.	     */            if (upTaskId->exitWhenEmpty && bufferEmpty)		{	        upTaskId->status = OK;		semGive (& upTaskId->uploadCompleteSem);		return (OK);		}        }    }/********************************************************************************* wvUploadStart - start upload of events to the host (WindView)** This routine starts uploading events from the event buffer to the host.* Events can be uploaded either continuously or in one pass until the* buffer is emptied.  If <uploadContinuously> is set to TRUE, the task* uploading events pends until more data arrives in the buffer.  If FALSE,* the buffer is flushed without waiting,  but this routine * returns immediately with an ID that can be used to kill the upload task.* Upload is done by spawning the task 'tWVUpload'.  The buffer to upload is * identified by <bufId>, and the upload path to use is identified by <pathId>.** This routine blocks if no event data is in the buffer, so it should* be called before event logging is started to ensure the buffer does* not overflow.** RETURNS: A valid WV_UPLOADTASK_ID if started for continuous* upload, a non-NULL value if started for one-pass upload, and NULL * if the task can not be spawned or memory for the descriptor * can not be allocated.**/WV_UPLOADTASK_ID wvUploadStart     (    BUFFER_ID bufId,	     /* event data buffer ID */    UPLOAD_ID pathId,	     /* upload path to host */    BOOL uploadContinuously  /* upload continuously if true */    )    {    WV_UPLOADTASK_ID upTaskId;	/* returned to later identify the upload task */    /* Check for valid parameters. */    if (bufId == NULL || pathId == NULL)	return (NULL);    /*      * Create and initialize the upload task descriptor to return to the      * user.  This id is necessary for stopping the task later.     */    if ((upTaskId = (WV_UPLOADTASK_ID) 		    malloc (sizeof (WV_UPLOADTASK_DESC))) == NULL)        {	logMsg ("wvUploadStart: can't alloc uploadTask id memory.\n",		 0,0,0,0,0,0);	return (NULL);	}    if (semBInit (& upTaskId->uploadCompleteSem, SEM_Q_PRIORITY, 		  SEM_EMPTY) == ERROR)        {	logMsg ("wvUploadStart: can't init uploadTask sem.\n",0,0,0,0,0,0);	return (NULL);	}    upTaskId->bufferId          = bufId;    upTaskId->uploadPathId      = pathId;    upTaskId->status		= OK;    if (uploadContinuously)        upTaskId->exitWhenEmpty = FALSE;    else        upTaskId->exitWhenEmpty = TRUE;    /* Now spawn the task. */    if ((upTaskId->uploadTaskId = taskSpawn ("tWVUpload", wvUploadTaskPriority, 				             wvUploadTaskOptions,		                             wvUploadTaskStackSize, wvUpload,					     (int) upTaskId, 0, 0, 0, 0, 0,					     0, 0, 0, 0)) == ERROR)        {	logMsg ("wvUploadStart: can't spawn uploadTask.\n",0,0,0,0,0,0);	return (NULL);        }    return (upTaskId);    }/********************************************************************************* wvUploadStop - stop upload of events to host (WindView)** This routine stops continuous upload of events to the host.  It does this* by making a request to the upload task to terminate after it has emptied* the buffer.  For this reason it is important to make sure data is no* longer being logged to the buffer before calling this routine.* * This task blocks until the buffer is emptied, and then frees memory* associated with <upTaskId>.** RETURNS: OK if the upload task terminates successfully, * or ERROR either if <upTaskId> is invalid or if the upload task terminates* with an ERROR.**/STATUS wvUploadStop     (    WV_UPLOADTASK_ID upTaskId    )    {    STATUS retStatus;    if (upTaskId == NULL)	return (ERROR);    /*      * Ask the upload task to flush the buffer and then exit.  The upload     * task may have emptied the buffer and be waiting on the buffer's     * threshold-crossed semaphore, so we give that semaphore so the task     * won't pend forever.     */    upTaskId->exitWhenEmpty = TRUE;    semGive (& upTaskId->bufferId->threshXSem);    /* Wait for flushing to complete, but only if uploader worked correctly */    if (upTaskId->status == OK)        semTake (& upTaskId->uploadCompleteSem, WAIT_FOREVER);    /* Free up the memory associated with the upload descriptor. */    semTerminate (& upTaskId->uploadCompleteSem);    retStatus = upTaskId->status;    free (upTaskId);    return (retStatus);    }/*******************************************************************************

⌨️ 快捷键说明

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