Esempio n. 1
0
static PHB_TASKINFO hb_taskSwitchLock( PHB_TASKMTX pMutex )
{
   PHB_TASKINFO pTask = pMutex->lockers;

   if( pTask )
   {
      pMutex->lockers = pTask->pBlockNext;
#ifdef HB_TASK_DEBUG
      if( pTask->locking != pMutex )
         hb_errInternal( HB_EI_ERRUNRECOV, "TaskSwitchLock: broken lock", NULL, NULL );
#endif
      pTask->locking = NULL;
      pTask->locked++;
      pMutex->task = pTask;
      pMutex->count = 1;
      if( pTask->state == TASK_SLEEPING )
      {
         hb_taskWakeUp( pTask );
         pTask->state = TASK_RUNNING;
      }
      else if( pTask->state != TASK_RUNNING )
         hb_errInternal( HB_EI_ERRUNRECOV, "TaskSwitchLock: task resumed", NULL, NULL );
   }
   return pTask;
}
Esempio n. 2
0
/* TODO: do not start task immediately */
void hb_taskResume( void * pTaskPtr )
{
   PHB_TASKINFO pTask = ( PHB_TASKINFO ) pTaskPtr, pCurrTask;

   if( s_currTask != pTask )
   {
      pCurrTask = s_currTask;
      switch( pTask->state )
      {
#if ! defined( HB_HAS_UCONTEXT )
         case TASK_INIT:
            /* save current execution context  */
            if( setjmp( s_currTask->context ) == 0 )
            {
               s_currTask = pTask;
               hb_taskStart();
               /* unreachable code */
            }
            break;
#endif
         case TASK_SLEEPING:
            hb_taskWakeUp( pTask );
            /* no break */
#if defined( HB_HAS_UCONTEXT )
         case TASK_INIT:
#endif
         case TASK_SUSPEND:
            pTask->state = TASK_RUNNING;
            /* no break */
         case TASK_RUNNING:
#if defined( HB_HAS_UCONTEXT )
            s_currTask = pTask;
            /* save current execution context and switch to the new one */
            swapcontext( &pCurrTask->context, &pTask->context );
#else
            /* save current execution context  */
            if( setjmp( s_currTask->context ) == 0 )
            {
               s_currTask = pTask;
               /* switch execution context */
               longjmp( pTask->context, 1 );
               /* unreachable code */
            }
#endif
            break;

         case TASK_DONE:
            break;

         case TASK_ZOMBIE:
            /* It should not happen - it's bug in user code */
            hb_errInternal( HB_EI_ERRUNRECOV, "TaskResume: zombie", NULL, NULL );
/*
         default:
            hb_errInternal( HB_EI_ERRUNRECOV, "TaskResume: corrupt", NULL, NULL );
 */
      }
   }
}
Esempio n. 3
0
static void hb_taskFinalize( PHB_TASKINFO pTask )
{
   pTask->data = NULL;

   if( pTask->joiners )
   {
      PHB_TASKINFO * pSleep = &s_taskSleep, pJoiner;
      while( *pSleep )
      {
         if( ( *pSleep )->joining == pTask )
         {
            pJoiner = *pSleep;
            pJoiner->joining = NULL;
            *pSleep = ( *pSleep )->pSleepNext;
            pJoiner->wakeup = 0;
            pJoiner->pSleepNext = s_taskSleep;
            s_taskSleep = pJoiner;
            if( --pTask->joiners == 0 )
               break;
         }
         else
            pSleep = &( *pSleep )->pSleepNext;
      }
#ifdef HB_TASK_DEBUG
      if( pTask->joiners )
         hb_errInternal( HB_EI_ERRUNRECOV, "TaskFinalize: dummy joiners", NULL, NULL );
#endif
   }

   /* it cannot happen for runing threads */

   /* remove from mutex lockers queue */
   if( pTask->locking )
   {
      PHB_TASKINFO * pLock = &pTask->locking->lockers;

      while( *pLock )
      {
         if( *pLock == pTask )
         {
            *pLock = pTask->pBlockNext;
            pTask->locking = NULL;
            break;
         }
         else
            pLock = &( *pLock )->pBlockNext;
      }
#ifdef HB_TASK_DEBUG
      if( pTask->locking )
         hb_errInternal( HB_EI_ERRUNRECOV, "TaskFinalize: dummy lock", NULL, NULL );
#endif
   }

   /* remove from condition queue */
   if( pTask->waiting )
   {
      PHB_TASKINFO * pWait = &pTask->waiting->waiters;

      while( *pWait )
      {
         if( *pWait == pTask )
         {
            *pWait = pTask->pWaitNext;
            pTask->waiting = NULL;
            break;
         }
         else
            pWait = &( *pWait )->pWaitNext;
      }
#ifdef HB_TASK_DEBUG
      if( pTask->waiting )
         hb_errInternal( HB_EI_ERRUNRECOV, "TaskFinalize: dummy cond", NULL, NULL );
#endif
   }

   if( pTask->state == TASK_SLEEPING )
      hb_taskWakeUp( pTask );

   pTask->state = TASK_DONE;

   if( pTask->locked )
   {
      PHB_TASKMTX pMutex = s_mutexList;

      while( pMutex )
      {
         if( pMutex->task == pTask && pMutex->count )
         {
            pTask->locked--;
            pMutex->task = NULL;
            pMutex->count = 0;
            hb_taskSwitchLock( pMutex );
         }
         pMutex = pMutex->next;
      }

#ifdef HB_TASK_DEBUG
      if( pTask->locked )
         hb_errInternal( HB_EI_ERRUNRECOV, "TaskFinalize: dummy lock", NULL, NULL );
#endif
   }

   if( pTask->detached )
   {
      pTask->state = TASK_ZOMBIE;
      if( pTask == s_currTask )
      {
         /* switch to next active task */
         hb_taskYield();
         /* unreachable code */
      }
      else
         hb_taskFree( pTask );
   }
}