代码拉取完成,页面将自动刷新
/*
* Copyright (C) 2001-2003 FhG Fokus
* Copyright (C) 2005-2006 Voice Sistem S.R.L
*
* This file is part of opensips, a free SIP server.
*
* opensips is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version
*
* opensips is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
#include <sys/types.h>
#include <sys/wait.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include "lib/dbg/profiling.h"
#include "config.h"
#include "dprint.h"
#include "daemonize.h"
#include "globals.h"
#include "pt.h"
#include "route.h"
#include "script_cb.h"
#include "blacklists.h"
#include "status_report.h"
#include "mem/shm_mem.h"
#include "db/db_insertq.h"
#include "net/net_udp.h"
#include "net/net_tcp.h"
#include "shutdown.h"
/**
* Clean up on exit. This should be called before exiting.
* \param show_status set to one to display the mem status
*/
void cleanup(int show_status)
{
LM_INFO("cleanup\n");
/*clean-up*/
#ifdef DBG_MALLOC
if (shm_memlog_size && mem_dbg_lock)
shm_dbg_unlock();
#endif
handle_ql_shutdown();
destroy_modules();
udp_destroy();
tcp_destroy();
destroy_timer();
if (shm_memlog_size)
shm_mem_disable_dbg();
destroy_stats_collector();
destroy_script_cb();
pv_free_extra_list();
tr_free_extra_list();
destroy_argv_list();
destroy_black_lists();
free_route_lists(sroutes); // this is just for testing purposes
#ifdef PKG_MALLOC
if (show_status){
LM_GEN1(memdump, "Memory status (pkg):\n");
pkg_status();
}
#endif
cleanup_log_level();
if (pt && (0
#if defined F_MALLOC || defined Q_MALLOC
|| mem_lock
#endif
#ifdef HP_MALLOC
|| mem_locks
#endif
))
shm_free(pt);
pt=0;
if (show_status){
LM_GEN1(memdump, "Memory status (shm):\n");
shm_status();
}
cleanup_log_cons_shm_table();
/* zero all shmem alloc vars that we still use */
shm_mem_destroy();
if (pid_file) unlink(pid_file);
if (pgid_file) unlink(pgid_file);
}
/**
* Send a signal to all child processes
* \param signum signal for killing the children
*/
void kill_all_children(int signum)
{
int r;
if (!pt)
return;
for (r = 1; r < counted_max_processes; r++) {
if (pt[r].pid == -1 || (pt[r].flags & OSS_PROC_DOING_DUMP))
continue;
/* as the PIDs are filled in by child processes, a 0 PID means
* an un-initalized procees; killing an uninitialized proc is
* very dangerous, so better wait for it to finish its init
* sequence by blocking until the pid is populated */
while (pt[r].pid == 0)
usleep(1000);
kill(pt[r].pid, signum);
}
}
/**
* SIGALRM "timeout" handler during the attendant's final cleanup,
* try to leave a core for future diagnostics.
*/
static void sig_alarm_abort(int signo)
{
/* LOG is not signal safe, but who cares, we are abort-ing anyway :-) */
LM_CRIT("BUG - shutdown timeout triggered, dying...\n");
abort();
}
/* RPC function send by main process to all worker processes supporting
* IPC in order to force a gracefull termination
*/
static void rpc_process_terminate(int sender_id, void *code)
{
#ifdef PKG_MALLOC
LM_GEN1(memdump, "Memory status (pkg):\n");
pkg_status();
#endif
/* simply terminate the process */
LM_DBG("Process %d exiting with code %d...\n",
process_no, (int)(long)code);
_ProfilerStop();
exit( (int)(long)code );
}
/* Implements full shutdown sequence (terminate processes and cleanup)
* To be called ONLY from MAIN process, not from workers !!!
*/
void shutdown_opensips( int status )
{
pid_t proc;
int i, n, p;
int chld_status;
sr_set_core_status_terminating();
distroy_log_event_cons();
/* terminate all processes */
/* first we try to terminate the processes via the IPC channel */
for( i=1,n=0 ; i<counted_max_processes; i++) {
/* Depending on the processes status, its PID may be:
* -1 - process not forked yet
* 0 - process forked but not fully configured by core
* >0 - process fully running
*/
if (pt[i].pid!=-1) {
/* use IPC (if avaiable) for a graceful termination */
if ( IPC_FD_WRITE(i)>0 ) {
LM_DBG("Asking process %d [%s] to terminate\n", i, pt[i].desc);
if (ipc_send_rpc( i, rpc_process_terminate, (void*)0)<0) {
LM_ERR("failed to trigger RPC termination for "
"process %d\n", i );
}
} else {
while (pt[i].pid==0) usleep(1000);
kill(pt[i].pid, SIGTERM);
}
n++;
}
}
/* now wait for the processes to finish */
i = GRACEFUL_SHUTDOWN_TIMEOUT * 100;
while( i && n ) {
proc = waitpid( -1, &chld_status, WNOHANG);
if (proc<=0) {
/* no process exited so far, do a small sleep before retry */
usleep(10000);
i--;
} else {
if ( (p=get_process_ID_by_PID(proc)) == -1 ) {
LM_DBG("unknown child process %d ended. Ignoring\n",proc);
} else {
LM_INFO("process %d(%d) [%s] terminated, "
"still waiting for %d more\n", p, proc, pt[p].desc, n-1);
/* mark the child process as terminated / not running */
pt[p].pid = -1;
status |= chld_status;
n--;
}
}
}
if (i==0 && n!=0) {
LM_DBG("force termination for all processes\n");
kill_all_children(SIGKILL);
}
_ProfilerStop();
/* Only one process is running now. Clean up and return overall status */
/* hack: force-unlock the shared memory lock(s) in case
some process crashed and let it locked; this will
allow an almost gracious shutdown */
shm_force_unlock();
signal(SIGALRM, sig_alarm_abort);
alarm(SHUTDOWN_TIMEOUT - i / 100);
cleanup(1);
alarm(0);
signal(SIGALRM, SIG_IGN);
stderr_dprint_tmp("Thank you for running " NAME "\n");
exit( status );
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。