Ejemplo n.º 1
0
/* insert lua process in recycle list */
void luaproc_recycle_insert( luaproc *lp ) {

  /* get exclusive access to recycled lua processes list */
  pthread_mutex_lock( &mutex_recycle_list );

  /* is recycle list full? */
  if ( list_count( &recycle_list ) >= recyclemax ) {
    /* destroy state */
    lua_close( luaproc_get_state( lp ));
  } else {
    /* insert lua process in recycle list */
    list_insert( &recycle_list, lp );
  }

  /* release exclusive access to recycled lua processes list */
  pthread_mutex_unlock( &mutex_recycle_list );
}
Ejemplo n.º 2
0
/* worker thread main function */
void *workermain( void *args ) {

  luaproc *lp;
  int procstat;

  /* main worker loop */
  while ( TRUE ) {
    /*
      wait until instructed to wake up (because there's work to do
      or because workers must be destroyed)
    */
    pthread_mutex_lock( &mutex_sched );
    while (( list_count( &ready_lp_list ) == 0 ) && ( destroyworkers <= 0 )) {
      pthread_cond_wait( &cond_wakeup_worker, &mutex_sched );
    }

    if ( destroyworkers > 0 ) {  /* check whether workers should be destroyed */
      
      destroyworkers--; /* decrease workers to be destroyed count */
      workerscount--; /* decrease active workers count */

      /* remove worker from workers table */
      lua_getglobal( workerls, LUAPROC_SCHED_WORKERS_TABLE );
      lua_pushlightuserdata( workerls, (void *)pthread_self( ));
      lua_pushnil( workerls );
      lua_rawset( workerls, -3 );
      lua_pop( workerls, 1 );

      pthread_cond_signal( &cond_wakeup_worker );  /* wake other workers up */
      pthread_mutex_unlock( &mutex_sched );
      pthread_exit( NULL );  /* destroy itself */
    }

    /* remove lua process from the ready queue */
    lp = list_remove( &ready_lp_list );
    pthread_mutex_unlock( &mutex_sched );

    /* execute the lua code specified in the lua process struct */
    procstat = luaproc_resume( luaproc_get_state( lp ), NULL,
                               luaproc_get_numargs( lp ));
    /* reset the process argument count */
    luaproc_set_numargs( lp, 0 );

    /* has the lua process sucessfully finished its execution? */
    if ( procstat == 0 ) {
      luaproc_set_status( lp, LUAPROC_STATUS_FINISHED );  
      luaproc_recycle_insert( lp );  /* try to recycle finished lua process */
      sched_dec_lpcount();  /* decrease active lua process count */
    }

    /* has the lua process yielded? */
    else if ( procstat == LUA_YIELD ) {

      /* yield attempting to send a message */
      if ( luaproc_get_status( lp ) == LUAPROC_STATUS_BLOCKED_SEND ) {
        luaproc_queue_sender( lp );  /* queue lua process on channel */
        /* unlock channel */
        luaproc_unlock_channel( luaproc_get_channel( lp ));
      }

      /* yield attempting to receive a message */
      else if ( luaproc_get_status( lp ) == LUAPROC_STATUS_BLOCKED_RECV ) {
        luaproc_queue_receiver( lp );  /* queue lua process on channel */
        /* unlock channel */
        luaproc_unlock_channel( luaproc_get_channel( lp ));
      }

      /* yield on explicit coroutine.yield call */
      else { 
        /* re-insert the job at the end of the ready process queue */
        pthread_mutex_lock( &mutex_sched );
        list_insert( &ready_lp_list, lp );
        pthread_mutex_unlock( &mutex_sched );
      }
    }

    /* or was there an error executing the lua process? */
    else {
      /* print error message */
      fprintf( stderr, "close lua_State (error: %s)\n",
               luaL_checkstring( luaproc_get_state( lp ), -1 ));
      lua_close( luaproc_get_state( lp ));  /* close lua state */
      sched_dec_lpcount();  /* decrease active lua process count */
    }
  }    
}