Example #1
0
int TenshiRunQuanta(TenshiRuntimeState s) {
  int ops_left = QUANTA_OPCODES;

  while (ops_left > 0) {
    TenshiActorState a;
    int ret = ActorDequeueHead(s, &a);
    if (ret != LUA_OK) return ret;

    if (!a) {
      printf("NOTHING TO RUN!\n");
      return LUA_OK;
    }

    ret = threading_run_ops(a->L, ops_left, &ops_left);
    if (ret == THREADING_ERROR) {
      printf("THERE WAS AN ERROR!\n");

      const char *msg = lua_tostring(a->L, -1);
      if (msg)  /* is error object a string? */
        luaL_traceback(a->L, a->L, msg, 0);  /* use standard traceback */
      else if (!lua_isnoneornil(a->L, -1)) {  /* non-string error object? */
        /* try its 'tostring' metamethod */
        if (!luaL_callmeta(a->L, -1, "__tostring"))
          lua_pushliteral(a->L, "(no error message)");
      }  /* else no error object, does nothing */

      const char *err_w_traceback = lua_tostring(a->L, -1);
      printf("%s\n", err_w_traceback);
      return LUA_ERRRUN;
    }

    if (ret == THREADING_EXITED) {
      printf("Thread exited!\n");
      ActorDestroy(a);
    } else if (ret == THREADING_YIELD) {
      printf("Thread yielded (blocked)!\n");
      ret = ActorSetBlocked(a);
      if (ret != LUA_OK) return ret;
    } else if (ret == THREADING_PREEMPT) {
      // Requeue it
      printf("Thread preempted!\n");
      ret = ActorSetRunnable(a, 0);
      if (ret != LUA_OK) return ret;
    }
  }

  return LUA_OK;
}
Example #2
0
int TenshiRunQuanta(TenshiRuntimeState s) {
  // Do timeouts
  ActorProcessTimeouts(s);

  // Run the sensor actor
  // Dup the function first, as it disappears when we exit
  // TODO(rqou): Will we have a problem with the hardcoded op limit?
  lua_pushvalue(s->sensor_actor->L, -1);
  int ret = threading_run_ops(s->sensor_actor->L, 1000, NULL);
  if (ret != THREADING_EXITED) {
    printf("There was an error running the sensor actor!\n");
    print_traceback(s->sensor_actor->L);
    return ret;
  }

  // Run the main code
  int ops_left = QUANTA_OPCODES;
  while (ops_left > 0) {
    TenshiActorState a;
    ret = ActorDequeueHead(s, &a);
    if (ret != LUA_OK) return ret;

    if (!a) {
      break;
    }

    ret = threading_run_ops(a->L, ops_left, &ops_left);
    if (ret == THREADING_ERROR) {
      printf("THERE WAS AN ERROR!\n");
      print_traceback(a->L);

      return LUA_ERRRUN;
    }

    if (ret == THREADING_EXITED) {
      printf("Thread exited!\n");
      ActorDestroy(a);
    } else if (ret == THREADING_YIELD) {
      printf("Thread yielded (blocked)!\n");
      ret = ActorSetBlocked(a);
      if (ret != LUA_OK) return ret;
    } else if (ret == THREADING_PREEMPT) {
      // Requeue it
      ret = ActorSetRunnable(a, 0);
      if (ret != LUA_OK) return ret;
    }
  }

  // Run the actuator actor
  // Dup the function first, as it disappears when we exit
  lua_pushvalue(s->actuator_actor->L, -1);
  ret = threading_run_ops(s->actuator_actor->L, 1000, NULL);
  if (ret != THREADING_EXITED) {
    printf("There was an error running the actuator actor!\n");
    print_traceback(s->actuator_actor->L);
    return ret;
  }

  lua_gc(s->L, LUA_GCCOLLECT, 0);

  return LUA_OK;
}