原创作者: mryufeng
阅读:1445次
评论:0条
更新时间:2011-06-01
ERTS要终止一个经常的时候调用一下函数
void
erts_do_exit_process(Process* p, Eterm reason)
{
ErtsLink* lnk;
ErtsMonitor *mon;
#ifdef ERTS_SMP
erts_pix_lock_t *pix_lock = ERTS_PID2PIXLOCK(p->id);
#endif
p->arity = 0; /* No live registers */
p->fvalue = reason;
#ifdef ERTS_SMP
ERTS_SMP_CHK_HAVE_ONLY_MAIN_PROC_LOCK(p);
/* By locking all locks (main lock is already locked) when going
to status P_EXITING, it is enough to take any lock when
looking up a process (erts_pid2proc()) to prevent the looked up
process from exiting until the lock has been released. */
erts_smp_proc_lock(p, ERTS_PROC_LOCKS_ALL_MINOR);
#endif
if (erts_system_profile_flags.runnable_procs && (p->status != P_WAITING)) {
profile_runnable_proc(p, am_inactive);
}
#ifdef ERTS_SMP
erts_pix_lock(pix_lock);
p->is_exiting = 1;
#endif
p->status = P_EXITING;
#ifdef ERTS_SMP
erts_pix_unlock(pix_lock);
if (ERTS_PROC_PENDING_EXIT(p)) {
/* Process exited before pending exit was received... */
p->pending_exit.reason = THE_NON_VALUE;
if (p->pending_exit.bp) {
free_message_buffer(p->pending_exit.bp);
p->pending_exit.bp = NULL;
}
}
cancel_suspend_of_suspendee(p, ERTS_PROC_LOCKS_ALL);
ERTS_SMP_MSGQ_MV_INQ2PRIVQ(p);
#endif
if (IS_TRACED_FL(p,F_TRACE_PROCS))
trace_proc(p, p, am_exit, reason);
erts_trace_check_exiting(p->id);
ASSERT((p->trace_flags & F_INITIAL_TRACE_FLAGS) == F_INITIAL_TRACE_FLAGS);
/* 清除进程用的定时器 */
cancel_timer(p); /* Always cancel timer just in case */
/* 清除bif定时器 */
if (p->bif_timers)
erts_cancel_bif_timers(p, ERTS_PROC_LOCKS_ALL);
/* 清除ETS 资源*/
if (p->flags & F_USING_DB)
db_proc_dead(p->id);
#ifdef ERTS_SMP
if (p->flags & F_HAVE_BLCKD_MSCHED)
erts_block_multi_scheduling(p, ERTS_PROC_LOCKS_ALL, 0, 1);
#endif
/* 清除 DLL驱动资源 */
if (p->flags & F_USING_DDLL) {
erts_ddll_proc_dead(p, ERTS_PROC_LOCKS_ALL);
}
/* 清除dist节点监控 */
if (p->nodes_monitors)
erts_delete_nodes_monitors(p, ERTS_PROC_LOCKS_ALL);
/*
* The registered name *should* be the last "erlang resource" to
* cleanup.
*/
/* 清除名字登记 */
if (p->reg)
(void) erts_unregister_name(p, ERTS_PROC_LOCKS_ALL, NULL, p->reg->name);
{
int pix;
ASSERT(internal_pid_index(p->id) < erts_max_processes);
pix = internal_pid_index(p->id);
erts_smp_proc_tab_lock();
erts_smp_sched_lock();
#ifdef ERTS_SMP
erts_pix_lock(pix_lock);
ASSERT(p->scheduler_data);
ASSERT(p->scheduler_data->current_process == p);
ASSERT(p->scheduler_data->free_process == NULL);
p->scheduler_data->current_process = NULL;
p->scheduler_data->free_process = p;
p->status_flags = 0;
#endif
process_tab[pix] = NULL; /* Time of death! */
ASSERT(erts_smp_atomic_read(&process_count) > 0);
erts_smp_atomic_dec(&process_count);
#ifdef ERTS_SMP
erts_pix_unlock(pix_lock);
#endif
erts_smp_sched_unlock();
if (p_next < 0) {
if (p_last >= p_next) {
p_serial++;
p_serial &= p_serial_mask;
}
p_next = pix;
}
erts_smp_proc_tab_unlock();
}
/*
* All "erlang resources" have to be deallocated before this point,
* e.g. registered name, so monitoring and linked processes can
* be sure that all interesting resources have been deallocated
* when the monitors and/or links hit.
*/
mon = p->monitors;
p->monitors = NULL; /* to avoid recursive deletion during traversal */
lnk = p->nlinks;
p->nlinks = NULL;
p->status = P_FREE;
erts_smp_proc_unlock(p, ERTS_PROC_LOCKS_ALL);
processes_busy--;
if ((p->flags & F_DISTRIBUTION) && p->dist_entry)
erts_do_net_exits(p->dist_entry, reason);
/*
* Pre-build the EXIT tuple if there are any links.
*/
if (lnk) {
Eterm tmp_heap[4];
Eterm exit_tuple;
Uint exit_tuple_sz;
Eterm* hp;
hp = &tmp_heap[0];
exit_tuple = TUPLE3(hp, am_EXIT, p->id, reason);
exit_tuple_sz = size_object(exit_tuple);
{
ExitLinkContext context = {p, reason, exit_tuple, exit_tuple_sz};
erts_sweep_links(lnk, &doit_exit_link, &context);
}
}
{
ExitMonitorContext context = {reason, p};
erts_sweep_monitors(mon,&doit_exit_monitor,&context);
}
delete_process(p);
#ifdef ERTS_ENABLE_LOCK_CHECK
erts_smp_proc_lock(p, ERTS_PROC_LOCK_MAIN); /* Make process_main() happy */
ERTS_SMP_CHK_HAVE_ONLY_MAIN_PROC_LOCK(p);
#endif
}
这些资源是进程拥有的 它有义务释放这些资源。 所以如果发现某些资源被莫名其妙的清除,请检查是不是进程异常退出!
void
erts_do_exit_process(Process* p, Eterm reason)
{
ErtsLink* lnk;
ErtsMonitor *mon;
#ifdef ERTS_SMP
erts_pix_lock_t *pix_lock = ERTS_PID2PIXLOCK(p->id);
#endif
p->arity = 0; /* No live registers */
p->fvalue = reason;
#ifdef ERTS_SMP
ERTS_SMP_CHK_HAVE_ONLY_MAIN_PROC_LOCK(p);
/* By locking all locks (main lock is already locked) when going
to status P_EXITING, it is enough to take any lock when
looking up a process (erts_pid2proc()) to prevent the looked up
process from exiting until the lock has been released. */
erts_smp_proc_lock(p, ERTS_PROC_LOCKS_ALL_MINOR);
#endif
if (erts_system_profile_flags.runnable_procs && (p->status != P_WAITING)) {
profile_runnable_proc(p, am_inactive);
}
#ifdef ERTS_SMP
erts_pix_lock(pix_lock);
p->is_exiting = 1;
#endif
p->status = P_EXITING;
#ifdef ERTS_SMP
erts_pix_unlock(pix_lock);
if (ERTS_PROC_PENDING_EXIT(p)) {
/* Process exited before pending exit was received... */
p->pending_exit.reason = THE_NON_VALUE;
if (p->pending_exit.bp) {
free_message_buffer(p->pending_exit.bp);
p->pending_exit.bp = NULL;
}
}
cancel_suspend_of_suspendee(p, ERTS_PROC_LOCKS_ALL);
ERTS_SMP_MSGQ_MV_INQ2PRIVQ(p);
#endif
if (IS_TRACED_FL(p,F_TRACE_PROCS))
trace_proc(p, p, am_exit, reason);
erts_trace_check_exiting(p->id);
ASSERT((p->trace_flags & F_INITIAL_TRACE_FLAGS) == F_INITIAL_TRACE_FLAGS);
/* 清除进程用的定时器 */
cancel_timer(p); /* Always cancel timer just in case */
/* 清除bif定时器 */
if (p->bif_timers)
erts_cancel_bif_timers(p, ERTS_PROC_LOCKS_ALL);
/* 清除ETS 资源*/
if (p->flags & F_USING_DB)
db_proc_dead(p->id);
#ifdef ERTS_SMP
if (p->flags & F_HAVE_BLCKD_MSCHED)
erts_block_multi_scheduling(p, ERTS_PROC_LOCKS_ALL, 0, 1);
#endif
/* 清除 DLL驱动资源 */
if (p->flags & F_USING_DDLL) {
erts_ddll_proc_dead(p, ERTS_PROC_LOCKS_ALL);
}
/* 清除dist节点监控 */
if (p->nodes_monitors)
erts_delete_nodes_monitors(p, ERTS_PROC_LOCKS_ALL);
/*
* The registered name *should* be the last "erlang resource" to
* cleanup.
*/
/* 清除名字登记 */
if (p->reg)
(void) erts_unregister_name(p, ERTS_PROC_LOCKS_ALL, NULL, p->reg->name);
{
int pix;
ASSERT(internal_pid_index(p->id) < erts_max_processes);
pix = internal_pid_index(p->id);
erts_smp_proc_tab_lock();
erts_smp_sched_lock();
#ifdef ERTS_SMP
erts_pix_lock(pix_lock);
ASSERT(p->scheduler_data);
ASSERT(p->scheduler_data->current_process == p);
ASSERT(p->scheduler_data->free_process == NULL);
p->scheduler_data->current_process = NULL;
p->scheduler_data->free_process = p;
p->status_flags = 0;
#endif
process_tab[pix] = NULL; /* Time of death! */
ASSERT(erts_smp_atomic_read(&process_count) > 0);
erts_smp_atomic_dec(&process_count);
#ifdef ERTS_SMP
erts_pix_unlock(pix_lock);
#endif
erts_smp_sched_unlock();
if (p_next < 0) {
if (p_last >= p_next) {
p_serial++;
p_serial &= p_serial_mask;
}
p_next = pix;
}
erts_smp_proc_tab_unlock();
}
/*
* All "erlang resources" have to be deallocated before this point,
* e.g. registered name, so monitoring and linked processes can
* be sure that all interesting resources have been deallocated
* when the monitors and/or links hit.
*/
mon = p->monitors;
p->monitors = NULL; /* to avoid recursive deletion during traversal */
lnk = p->nlinks;
p->nlinks = NULL;
p->status = P_FREE;
erts_smp_proc_unlock(p, ERTS_PROC_LOCKS_ALL);
processes_busy--;
if ((p->flags & F_DISTRIBUTION) && p->dist_entry)
erts_do_net_exits(p->dist_entry, reason);
/*
* Pre-build the EXIT tuple if there are any links.
*/
if (lnk) {
Eterm tmp_heap[4];
Eterm exit_tuple;
Uint exit_tuple_sz;
Eterm* hp;
hp = &tmp_heap[0];
exit_tuple = TUPLE3(hp, am_EXIT, p->id, reason);
exit_tuple_sz = size_object(exit_tuple);
{
ExitLinkContext context = {p, reason, exit_tuple, exit_tuple_sz};
erts_sweep_links(lnk, &doit_exit_link, &context);
}
}
{
ExitMonitorContext context = {reason, p};
erts_sweep_monitors(mon,&doit_exit_monitor,&context);
}
delete_process(p);
#ifdef ERTS_ENABLE_LOCK_CHECK
erts_smp_proc_lock(p, ERTS_PROC_LOCK_MAIN); /* Make process_main() happy */
ERTS_SMP_CHK_HAVE_ONLY_MAIN_PROC_LOCK(p);
#endif
}
这些资源是进程拥有的 它有义务释放这些资源。 所以如果发现某些资源被莫名其妙的清除,请检查是不是进程异常退出!
评论 共 0 条 请登录后发表评论