/** @ingroup n8_event
 * @brief Sets the global flag to alert the callback thread to shutdown.
 *
 * This function is called by N8_TerminateAPI. It Sets the flag n8_thread
 * flag to alert the callback thread to shutdown or frees resources if
 * polling was configured.
 *
 * @par Externals
 *    n8_callback_gp    - Pointer to the callback threads data structure.
 *
 * @return
 *    N8_STATUS_OK - all's well.<br>
 *
 * @par Errors
 *    <description of possible errors><br>
 *
 * @par Assumptions
 *****************************************************************************/
N8_Status_t callbackShutdown(void)
{

   if (n8_callbackData_gp->n8_thread == FALSE)
   {
      /* There was no callback thread started, so it is safe to deallocate */
      /* resources immediately.                                            */
      n8_callbackData_gp->eventMax = 0;
      N8_deleteProcessSem(&n8_callbackData_gp->eventLock);
      N8_UFREE(n8_callbackData_gp);
   }
   else
   {
      /* If a callback thread was started, just set the n8_thread   */
      /* flag so the thread terminates, then deallocate resources.  */
      n8_callbackData_gp->n8_thread = FALSE;

#ifdef __KERNEL__
      send_sig(SIGKILL, threadStruct, 0);
#endif
   }


   return(N8_STATUS_OK);
}
Exemple #2
0
/** @ingroup user_util
 * @brief Delete a buffer allocated by N8_CreateBuffer
 *
 *  @param buf_p               RO:  buffer
 *
 * @par Externals
 *    None
 *
 * @return
 *    Status
 *
 * @par Errors
 *    N8_STATUS_OK, N8_INVALID_OBJECT
 *
 * @par Assumptions
 *****************************************************************************/
N8_Status_t N8_DeleteBuffer(N8_Buffer_t *buf_p)
{
    N8_Status_t ret = N8_STATUS_OK;
    if (buf_p != NULL)
    {
        N8_UFREE(buf_p);
    }
    else
    {
        ret = N8_INVALID_OBJECT;
    }
    return ret;
} /* N8_DeleteBuffer */
/** @ingroup n8_event
 * @brief Runs as a seperate thread polling the list of events and completing 
 *        them.
 *
 * This function is started as a seperate thread. It continually runs through
 * the SDK's internal list of events, checking each one for its 
 * completion status. If the event is completed, the user's callback is 
 * invoked and the event freed.
 *
 * @par Externals
 *
 * @return
 *    N8_STATUS_OK - all's well.<br>
 *
 * @par Errors
 *    <description of possible errors><br>
 *
 * @par Assumptions
 *    This is the only function that should increment eventReadIndex,
 *    the read index in the SDK's list of Events.
 *    N8_EventPoll should not be called if this thread is running.
 *****************************************************************************/
N8_Status_t n8_callbackThread(N8_CallbackData_t *callbackData_p)
{
   int         nextRead;
   N8_Event_t *events_p;
   QMgrRequest_t *qreq_p = NULL;
   N8_Status_t usrStatus;

   /* Perform Linux Kernal specific initialization */
#ifdef __KERNEL__
   threadStruct = current;
   /* Mask out the unwanted signals */
   current->blocked.sig[0] |= sigmask(SIGINT) | sigmask(SIGTERM);
   recalc_sigpending(current);

   /* set name of this process (max 15 chars + 0 !) */
   strcpy(current->comm, "NSP2000 Thread");
#endif
        
   while (callbackData_p->n8_thread == TRUE)
   {
      if (callbackData_p->eventReadIndex != callbackData_p->eventWriteIndex)
      {
         events_p = &callbackData_p->n8_Events[callbackData_p->eventReadIndex];
         qreq_p = (QMgrRequest_t *) events_p->state;

         if ( qreq_p->requestStatus == N8_QUEUE_REQUEST_FINISHED )
         {
            if ( qreq_p->requestError != N8_QUEUE_REQUEST_ERROR )
            {
               /* Do the callback if needed. */
               if ( qreq_p->callback != NULL )
               {
                  qreq_p->callback( qreq_p );
               }
               /* events_p->status = N8_QUEUE_REQUEST_FINISHED; */
	       usrStatus = N8_STATUS_OK;
            }
            else
            {
               /* events_p->status = N8_QUEUE_REQUEST_COMMAND_ERROR; */
	       usrStatus = N8_HARDWARE_ERROR;
            }

            /* free the request. */
            freeRequest((API_Request_t *)qreq_p);

            /* Perform the user's callback. */
            if (events_p->usrCallback)
            {
               events_p->usrCallback( events_p->usrData, usrStatus );
            }

            /* Free the position in the Event queue */
            nextRead = callbackData_p->eventReadIndex + 1;
            if (nextRead == callbackData_p->eventMax)
            {
               nextRead = 0;
            }
            callbackData_p->eventReadIndex = nextRead;
	 }
         else
         {
            N8_WaitOnRequest(callbackData_p->timeout);
         }
      }
      else
      {
         N8_WaitOnRequest(callbackData_p->timeout);
      }
   }

   /* Free the resources allocated by callback initialization.          */
   /* This is done here instead of in callbackShutdown to avoid freeing */
   /* resources while the callback thread continues to reference them.  */
   callbackData_p->eventMax = 0;
   N8_deleteProcessSem(&callbackData_p->eventLock);
   N8_UFREE(callbackData_p);

   return N8_STATUS_OK;
}