/** * Timer Process function. * It calls timer_loop(). * @param returns - whether on shutdown this function should return or exit * @returns if returns is set then on shutdown, else never and on shutdown it exits */ void timer_process(int returns) { LM_INFO("Timer process starting up...\n"); timer_loop(); LM_INFO("... Timer process finished\n"); if (!returns) { #ifdef CDP_FOR_SER #else #ifdef PKG_MALLOC #ifdef PKG_MALLOC LM_DBG("Timer Memory status (pkg):\n"); //pkg_status(); #ifdef pkg_sums pkg_sums(); #endif #endif #endif dp_del_pid(getpid()); #endif exit(0); } }
/** call it before exiting; if show_status==1, mem status is displayed */ void destroy_memory(int show_status) { /*clean-up*/ if (mem_lock) shm_unlock(); /* hack: force-unlock the shared memory lock in case some process crashed and let it locked; this will allow an almost gracious shutdown */ #ifdef SHM_MEM if (show_status){ LOG(memlog, "Memory status (shm):\n"); //shm_status(); #ifndef SER_MOD_INTERFACE shm_sums(); #endif } /* zero all shmem alloc vars that we still use */ #ifdef WHARF #else shm_mem_destroy(); #endif #endif #ifdef PKG_MALLOC if (show_status){ LOG(memlog, "Memory status (pkg):\n"); //pkg_status(); #ifndef SER_MOD_INTERFACE pkg_sums(); #endif } #endif }
/* Dumps pkg memory status. * Per-child process callback that is called * when mem_dump_pkg cfg var is changed. */ void mem_dump_pkg_cb(str *gname, str *name) { int old_memlog; int memlog; if (cfg_get(core, core_cfg, mem_dump_pkg) == my_pid()) { /* set memlog to ALERT level to force printing the log messages */ old_memlog = cfg_get(core, core_cfg, memlog); memlog = L_ALERT; /* ugly hack to temporarily switch memlog to something visible, * possible race with a parallel cfg_set */ ((struct cfg_group_core*)core_cfg)->memlog=memlog; if (cfg_get(core, core_cfg, mem_summary) & 1) { LOG(memlog, "Memory status (pkg) of process %d:\n", my_pid()); pkg_status(); } if (cfg_get(core, core_cfg, mem_summary) & 4) { LOG(memlog, "Memory still-in-use summary (pkg) of process %d:\n", my_pid()); pkg_sums(); } ((struct cfg_group_core*)core_cfg)->memlog=old_memlog; } }
/** * The Receiver Process - calls the receiv_loop and it never returns. * @param p - the peer it is associated with or NULL for the unknown peers receiver * @returns never, when disconnected it will exit */ void receiver_process(peer *p) { LM_INFO("receiver_process(): [%.*s] Receiver process doing init on new process...\n", p?p->fqdn.len:0,p?p->fqdn.s:0); if (p) if (!add_serviced_peer(p)) goto done; LM_INFO("receiver_process(): [%.*s] Receiver process starting up...\n", p?p->fqdn.len:0,p?p->fqdn.s:0); log_serviced_peers(); if (receive_loop(p)<0){ LM_INFO("receiver_process(): [%.*s] receive_loop() return -1 (error)!\n", p?p->fqdn.len:0,p?p->fqdn.s:0); } done: if (!*shutdownx){ LM_INFO("receiver_process(): [%.*s]... Receiver process cleaning-up - should not happen unless shuting down!\n", p?p->fqdn.len:0,p?p->fqdn.s:0); } LM_INFO("receiver_process(): [%.*s]... Receiver process cleaning-up.\n", p?p->fqdn.len:0,p?p->fqdn.s:0); while(serviced_peers){ disconnect_serviced_peer(serviced_peers,0); drop_serviced_peer(serviced_peers,0); } /* remove pid from list of running processes */ dp_del_pid(getpid()); #ifdef CDP_FOR_SER #else #ifdef PKG_MALLOC #ifdef PKG_MALLOC LM_DBG("Receiver[%.*s] Memory status (pkg):\n", p?p->fqdn.len:0,p?p->fqdn.s:0); //pkg_status(); #ifdef pkg_sums pkg_sums(); #endif #endif #endif #endif LM_INFO("receiver_process(): [%.*s]... Receiver process finished.\n", p?p->fqdn.len:0,p?p->fqdn.s:0); exit(0); }
/* and in here we also loop for exosip events*/ void acceptor_process(dp_config *cfg) { int i,k; unsigned int sock; LOG(L_INFO,"INFO:Acceptor process starting up...\n"); listening_socks = pkg_malloc((cfg->acceptors_cnt+1)*sizeof(int)); if (!listening_socks){ LOG_NO_MEM("pkg",(cfg->acceptors_cnt+1)*sizeof(int)); goto done; } memset(listening_socks,0,(cfg->acceptors_cnt+1)*sizeof(int)); k=0; for(i=0;i<cfg->acceptors_cnt;i++) if (create_socket(cfg->acceptors[i].port,cfg->acceptors[i].bind,&sock)){ listening_socks[k++]=sock; } LOG(L_INFO,"INFO:... Acceptor opened sockets. Entering accept loop ...\n"); accept_loop(); for(i=0;listening_socks[i];i++) close(listening_socks[i]); if (listening_socks) pkg_free(listening_socks); #ifdef CDP_FOR_SER #else #ifdef PKG_MALLOC #ifdef PKG_MALLOC LOG(memlog, "Acceptor Memory status (pkg):\n"); //pkg_status(); #ifdef pkg_sums pkg_sums(); #endif #endif #endif dp_del_pid(getpid()); #endif done: LOG(L_INFO,"INFO:... Acceptor process finished\n"); exit(0); }
/** * This is the main worker process. * Takes tasks from the queue in a loop and processes them by calling the registered callbacks. * @param id - id of the worker * @returns never, exits on shutdown. */ void worker_process(int id) { task_t t; cdp_cb_t *cb; int r; LM_INFO("[%d] Worker process started...\n", id); /* init the application level for this child */ while (1) { if (shutdownx && (*shutdownx)) break; cfg_update(); t = take_task(); if (!t.msg) { if (shutdownx && (*shutdownx)) break; LM_INFO("[%d] got empty task Q(%d/%d)\n", id, tasks->start, tasks->end); continue; } LM_DBG("worker_process(): [%d] got task Q(%d/%d)\n", id, tasks->start, tasks->end); r = is_req(t.msg); for (cb = callbacks->head; cb; cb = cb->next) (*(cb->cb))(t.p, t.msg, *(cb->ptr)); if (r) { AAAFreeMessage(&(t.msg)); } else { /* will be freed by the user in upper api */ /*AAAFreeMessage(&(t.msg));*/ } } worker_poison_queue(); LM_INFO("[%d]... Worker process finished\n", id); #ifdef CDP_FOR_SER #else #ifdef PKG_MALLOC LM_DBG("Worker[%d] Memory status (pkg):\n", id); //pkg_status(); #ifdef pkg_sums pkg_sums(); #endif #endif dp_del_pid(getpid()); #endif exit(0); }
/** * The Receiver Process - calls the receiv_loop and it never returns. * @param sock - socket to receive data from * @returns never, when disconnected it will exit */ void receiver_process(int sock) { LOG(L_INFO,"INFO:receiver_process(): [%d] Receiver process starting up...\n",sock); receive_loop(sock); LOG(L_INFO,"INFO:receiver_process(): [%d]... Receiver process cleaning-up.\n",sock); close(sock); close(pipe_fd); close(pipe_fd_out); remove(pipe_name.s); if (this_peer){ lock_get(this_peer->lock); this_peer->send_pipe.s=0; this_peer->send_pipe.len=0; lock_release(this_peer->lock); } shm_free(pipe_name.s); //done: /* remove pid from list of running processes */ dp_del_pid(getpid()); #ifdef CDP_FOR_SER drop_my_process(); #else #ifdef PKG_MALLOC #ifdef PKG_MALLOC LOG(memlog, "Receiver[%d] Memory status (pkg):\n",sock); //pkg_status(); #ifdef pkg_sums pkg_sums(); #endif #endif #endif #endif LOG(L_INFO,"INFO:receiver_process(): [%d]... Receiver process finished.\n",sock); exit(0); }
static int dbg_pkg_summary(struct sip_msg* msg, char* foo, char* bar) { pkg_sums(); return 1; }
static int ki_pkg_summary(sip_msg_t* msg) { pkg_sums(); return 1; }
/** * Shutdown the CDiameterPeer nicely. * It stops the workers, disconnects peers, drops timers and wait for all processes to exit. */ void diameter_peer_destroy() { int pid,status; handler *h; lock_get(shutdownx_lock); if (*shutdownx) { /* already other process is cleaning stuff */ lock_release(shutdownx_lock); return; }else { /* indicating that we are shuting down */ *shutdownx = 1; lock_release(shutdownx_lock); } worker_poison_queue(); /* wait for all childs to clean up nicely (acceptor, receiver, timer, workers) */ LOG(L_INFO,"INFO:destroy_diameter_peer(): Terminating all childs...\n"); while(pid_list->tail){ pid = dp_last_pid(); if (pid<=0||pid==getpid()){ dp_del_pid(pid); continue; } LOG(L_INFO,"INFO:destroy_diameter_peer(): Waiting for child [%d] to terminate...\n",pid); if (waitpid(pid,&status,0)<0){ dp_del_pid(pid); continue; } if (!WIFEXITED(status) /*|| WIFSIGNALED(status)*/){ worker_poison_queue(); sleep(1); } else { dp_del_pid(pid); } } LOG(L_INFO,"INFO:destroy_diameter_peer(): All processes terminated. Cleaning up.\n"); /* clean upt the timer */ timer_cdp_destroy(); /* cleaning up workers */ worker_destroy(); /* cleaning peer_manager */ peer_manager_destroy(); /* cleaning up sessions */ session_destroy(); /* cleaning up global vars */ /* lock_get(pid_list_lock);*/ shm_free(dp_first_pid); shm_free(pid_list); lock_destroy(pid_list_lock); lock_dealloc((void*)pid_list_lock); shm_free(shutdownx); lock_destroy(shutdownx_lock); lock_dealloc((void*)shutdownx_lock); lock_get(handlers_lock); while(handlers->head){ h = handlers->head->next; shm_free(handlers->head); handlers->head = h; } lock_destroy(handlers_lock); lock_dealloc((void*)handlers_lock); shm_free(handlers); free_dp_config(config); LOG(L_CRIT,"INFO:destroy_diameter_peer(): Bye Bye from C Diameter Peer test\n"); #ifndef CDP_FOR_SER #ifdef PKG_MALLOC LOG(memlog, "Memory status (pkg):\n"); //pkg_status(); #ifdef pkg_sums pkg_sums(); #endif #endif #ifdef SHM_MEM LOG(memlog, "Memory status (shm):\n"); //shm_status(); #ifdef shm_sums shm_sums(); #endif /* zero all shmem alloc vars that we still use */ shm_mem_destroy(); #endif #endif }