/** * 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); }
/** * 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 }