/* Note that now, once the master object loads once, there is ALWAYS a * master object, so the only way this can fail is if the master object * hasn't loaded yet. In that case, we return (svalue_t *)-1, and the * calling routine should let the check succeed. 失败只可能是还没有load进master 这像是在让master调用函数? */ svalue_t *apply_master_ob(int fun, int num_arg) /* 将master应用起来? */ { if (!master_ob) { pop_n_elems(num_arg); /* 只要master还没有load进来,就将栈清空? */ return (svalue_t *)-1; } if (master_applies[fun].func) { /* 这里会调用不同的函数,函数都在里边? */ #ifdef TRACE if (TRACEP(TRACE_APPLY)) { do_trace("master apply", master_applies[fun].func->name, "\n"); } #endif DEBUG_CHECK(master_ob->flags & O_SWAPPED, "Master object swapped!\n"); call_direct(master_ob, master_applies[fun].index, ORIGIN_DRIVER, num_arg); /* 像是在调用函数? */ free_svalue(&apply_ret_value, "apply_master_ob"); apply_ret_value = *sp--; /* 从栈中取出返回值 */ return &apply_ret_value; } else { pop_n_elems(num_arg); return 0; } }
void call_heart_beat() { object_t *ob; heart_beat_t *curr_hb; error_context_t econ; current_interactive = 0; if ((num_hb_to_do = num_hb_objs)) { num_hb_calls++; heart_beat_index = 0; save_context(&econ); while (1) { ob = (curr_hb = &heart_beats[heart_beat_index])->ob; DEBUG_CHECK(!(ob->flags & O_HEART_BEAT), "Heartbeat not set in object on heartbeat list!"); /* is it time to do a heart beat ? */ curr_hb->heart_beat_ticks--; if (ob->prog->heart_beat != 0) { if (curr_hb->heart_beat_ticks < 1) { object_t *new_command_giver; curr_hb->heart_beat_ticks = curr_hb->time_to_heart_beat; current_heart_beat = ob; new_command_giver = ob; #ifndef NO_SHADOWS while (new_command_giver->shadowing) new_command_giver = new_command_giver->shadowing; #endif #ifndef NO_ADD_ACTION if (!(new_command_giver->flags & O_ENABLE_COMMANDS)) new_command_giver = 0; #endif #ifdef PACKAGE_MUDLIB_STATS add_heart_beats(&ob->stats, 1); #endif set_eval(max_cost); if (SETJMP(econ.context)) { restore_context(&econ); } else { save_command_giver(new_command_giver); call_direct(ob, ob->prog->heart_beat - 1, ORIGIN_DRIVER, 0); pop_stack(); /* pop the return value */ restore_command_giver(); } current_object = 0; } } if (++heart_beat_index == num_hb_to_do) break; } pop_context(&econ); if (heart_beat_index < num_hb_to_do) perc_hb_probes = 100 * (float) heart_beat_index / num_hb_to_do; else perc_hb_probes = 100.0; heart_beat_index = num_hb_to_do = 0; } current_prog = 0; current_heart_beat = 0; look_for_objects_to_swap(); #ifdef PACKAGE_MUDLIB_STATS mudlib_stats_decay(); #endif } /* call_heart_beat() */
static void call_heart_beat() { object_t *ob; heart_beat_t *curr_hb; error_context_t econ; #ifdef WIN32 static long Win32Thread = -1; #endif heart_beat_flag = 0; #ifdef SIGALRM signal(SIGALRM, sigalrm_handler); #endif #ifdef HAS_UALARM ualarm(HEARTBEAT_INTERVAL, 0); #else # ifdef WIN32 if (Win32Thread == -1) Win32Thread = _beginthread( /* This shouldn't be necessary b/c alarm_loop is already declared as this. Microsoft lossage? -Beek */ (void (__cdecl *)(void *)) alarm_loop, 256, 0); # else alarm(SYSV_HEARTBEAT_INTERVAL); /* defined in config.h */ # endif #endif current_interactive = 0; if ((num_hb_to_do = num_hb_objs)) { num_hb_calls++; heart_beat_index = 0; save_context(&econ); while (!heart_beat_flag) { ob = (curr_hb = &heart_beats[heart_beat_index])->ob; DEBUG_CHECK(!(ob->flags & O_HEART_BEAT), "Heartbeat not set in object on heartbeat list!"); DEBUG_CHECK(ob->flags & O_SWAPPED, "Heartbeat in swapped object.\n"); /* is it time to do a heart beat ? */ curr_hb->heart_beat_ticks--; if (ob->prog->heart_beat != 0) { if (curr_hb->heart_beat_ticks < 1) { object_t *new_command_giver; curr_hb->heart_beat_ticks = curr_hb->time_to_heart_beat; current_heart_beat = ob; new_command_giver = ob; #ifndef NO_SHADOWS while (new_command_giver->shadowing) new_command_giver = new_command_giver->shadowing; #endif #ifndef NO_ADD_ACTION if (!(new_command_giver->flags & O_ENABLE_COMMANDS)) new_command_giver = 0; #endif #ifdef PACKAGE_MUDLIB_STATS add_heart_beats(&ob->stats, 1); #endif eval_cost = max_cost; if (SETJMP(econ.context)) { restore_context(&econ); } else { save_command_giver(new_command_giver); call_direct(ob, ob->prog->heart_beat - 1, ORIGIN_DRIVER, 0); pop_stack(); /* pop the return value */ restore_command_giver(); } current_object = 0; } } if (++heart_beat_index == num_hb_to_do) break; } pop_context(&econ); if (heart_beat_index < num_hb_to_do) perc_hb_probes = 100 * (float) heart_beat_index / num_hb_to_do; else perc_hb_probes = 100.0; heart_beat_index = num_hb_to_do = 0; } current_prog = 0; current_heart_beat = 0; look_for_objects_to_swap(); call_out(); #ifdef PACKAGE_MUDLIB_STATS mudlib_stats_decay(); #endif } /* call_heart_beat() */