Definition in file diameter_peer.c.
#include <stdlib.h>
#include <sys/wait.h>
#include <signal.h>
#include <stdio.h>
#include "utils.h"
#include "diameter_peer.h"
#include "config.h"
#include "acceptor.h"
#include "timer.h"
#include "peermanager.h"
#include "worker.h"
#include "api_process.h"
#include "transaction.h"
#include "session.h"
#include "../../pt.h"
Go to the source code of this file.
Functions | |
| int | dp_add_pid (pid_t pid) |
| Add a pid to the local process list. | |
| int | dp_last_pid () |
| Returns the last pid in the local process list. | |
| void | dp_del_pid (pid_t pid) |
| Delete a pid from the process list. | |
| int | diameter_peer_init (char *cfg_filename) |
| Initialize the CDiameterPeer from a configuration file. | |
| int | diameter_peer_start (int blocking) |
| Start the CDiameterPeer operations. | |
| void | diameter_peer_destroy () |
| Shutdown the CDiameterPeer nicely. | |
Variables | |
| dp_config * | config = 0 |
| Configuration for this diameter peer. | |
| int * | shutdownx = 0 |
| whether a shutdown is in progress | |
| gen_lock_t * | shutdownx_lock |
| lock used on shutdown | |
| pid_t * | dp_first_pid |
| first pid that we started from | |
| pid_list_head_t * | pid_list |
| list of local processes | |
| gen_lock_t * | pid_list_lock |
| lock for list of local processes | |
| handler_list * | handlers |
| list of handlers | |
| gen_lock_t * | handlers_lock |
| lock for list of handlers | |
| int | memlog |
| int dp_add_pid | ( | pid_t | pid | ) | [inline] |
Add a pid to the local process list.
| pid | newly forked pid |
Definition at line 95 of file diameter_peer.c.
References pid_list_head_t::head, LOG_NO_MEM, _pid_list_t::next, _pid_list_t::pid, pid_list, pid_list_lock, _pid_list_t::prev, and pid_list_head_t::tail.
00096 { 00097 pid_list_t *n; 00098 lock_get(pid_list_lock); 00099 n = shm_malloc(sizeof(pid_list_t)); 00100 if (!n){ 00101 LOG_NO_MEM("shm",sizeof(pid_list_t)); 00102 lock_release(pid_list_lock); 00103 return 0; 00104 } 00105 n->pid = pid; 00106 n->next = 0; 00107 n->prev = pid_list->tail; 00108 if (!pid_list->head) pid_list->head = n; 00109 if (pid_list->tail) pid_list->tail->next = n; 00110 pid_list->tail = n; 00111 lock_release(pid_list_lock); 00112 return 1; 00113 }
| int dp_last_pid | ( | ) | [inline] |
Returns the last pid in the local process list.
Definition at line 118 of file diameter_peer.c.
References _pid_list_t::pid, pid_list, pid_list_lock, and pid_list_head_t::tail.
Referenced by diameter_peer_destroy().
00119 { 00120 int pid; 00121 lock_get(pid_list_lock); 00122 if (pid_list->tail) pid = pid_list->tail->pid; 00123 else pid = -1; 00124 lock_release(pid_list_lock); 00125 return pid; 00126 }
| void dp_del_pid | ( | pid_t | pid | ) | [inline] |
Delete a pid from the process list.
| pid | - the pid to remove |
Definition at line 132 of file diameter_peer.c.
References pid_list_head_t::head, _pid_list_t::next, _pid_list_t::pid, pid_list, pid_list_lock, _pid_list_t::prev, and pid_list_head_t::tail.
00133 { 00134 pid_list_t *i; 00135 lock_get(pid_list_lock); 00136 i = pid_list->head; 00137 if (!i) { 00138 lock_release(pid_list_lock); 00139 return; 00140 } 00141 while(i && i->pid!=pid) i = i->next; 00142 if (i){ 00143 if (i->prev) i->prev->next = i->next; 00144 else pid_list->head = i->next; 00145 if (i->next) i->next->prev = i->prev; 00146 else pid_list->tail = i->prev; 00147 shm_free(i); 00148 } 00149 lock_release(pid_list_lock); 00150 }
| int diameter_peer_init | ( | char * | cfg_filename | ) |
Initialize the CDiameterPeer from a configuration file.
The file is kept as dtd. See configdtd.h for the DTD and ConfigExample.xml.
| cfg_filename | - file with the configuration |
Definition at line 159 of file diameter_peer.c.
References api_callback(), cb_add(), config, dp_first_pid, free_dp_config(), handlers, handlers_lock, handler_list_t::head, pid_list_head_t::head, log_dp_config(), LOG_NO_MEM, _pid_list_t::next, parse_dp_config(), peer_manager_init(), pid_list, pid_list_lock, session_init(), shutdownx, shutdownx_lock, handler_list_t::tail, timer_cdp_init(), trans_init(), and worker_init().
Referenced by cdp_init().
00160 { 00161 pid_list_t *i,*j; 00162 00163 config = parse_dp_config(cfg_filename); 00164 if (!config) { 00165 LOG(L_ERR,"ERROR:init_diameter_peer(): Error loading configuration file. Aborting...\n"); 00166 goto error; 00167 } 00168 log_dp_config(L_INFO,config); 00169 00170 dp_first_pid = shm_malloc(sizeof(pid_t)); 00171 if (!dp_first_pid){ 00172 LOG_NO_MEM("shm",sizeof(pid_t)); 00173 goto error; 00174 } 00175 *dp_first_pid = getpid(); 00176 00177 shutdownx = shm_malloc(sizeof(int)); 00178 if (!shutdownx){ 00179 LOG_NO_MEM("shm",sizeof(int)); 00180 goto error; 00181 } 00182 *shutdownx = 0; 00183 00184 shutdownx_lock = lock_alloc(); 00185 if (!shutdownx_lock){ 00186 LOG_NO_MEM("shm",sizeof(gen_lock_t)); 00187 goto error; 00188 } 00189 shutdownx_lock = lock_init(shutdownx_lock); 00190 00191 handlers_lock = lock_alloc(); 00192 if (!handlers_lock){ 00193 LOG_NO_MEM("shm",sizeof(gen_lock_t)); 00194 goto error; 00195 } 00196 handlers_lock = lock_init(handlers_lock); 00197 00198 handlers = shm_malloc(sizeof(handler_list)); 00199 if (!handlers){ 00200 LOG_NO_MEM("shm",sizeof(handler_list)); 00201 goto error; 00202 } 00203 handlers->head=0; 00204 handlers->tail=0; 00205 00206 /* init the pid list */ 00207 pid_list = shm_malloc(sizeof(pid_list_head_t)); 00208 pid_list_lock = lock_alloc(); 00209 pid_list_lock = lock_init(pid_list_lock); 00210 00211 /* init shared mem pointers before forking */ 00212 timer_cdp_init(); 00213 worker_init(); 00214 00215 /* init the peer manager */ 00216 peer_manager_init(config); 00217 00218 /* init the session */ 00219 if (!session_init()) goto error; 00220 00221 00222 /* init diameter transactions */ 00223 trans_init(); 00224 00225 /* add callback for messages - used to implement the API */ 00226 cb_add(api_callback,0); 00227 00228 return 1; 00229 00230 error: 00231 if (shutdownx) shm_free(shutdownx); 00232 if (config) free_dp_config(config); 00233 i = pid_list->head; 00234 while(i){ 00235 j = i->next; 00236 shm_free(i); 00237 i = j; 00238 } 00239 shm_free(pid_list); 00240 lock_get(pid_list_lock); 00241 lock_destroy(pid_list_lock); 00242 lock_dealloc((void*)pid_list_lock); 00243 return 0; 00244 00245 }
| int diameter_peer_start | ( | int | blocking | ) |
Start the CDiameterPeer operations.
It forks all the processes required.
| blocking | - if this is set, use the calling processes for the timer and never return; else fork a new one for the timer and return |
Definition at line 255 of file diameter_peer.c.
References acceptor_process(), CDP_FOR_SER, config, dp_add_pid(), process_no, timer_process(), worker_process(), and dp_config::workers.
Referenced by cdp_child_init().
00256 { 00257 int pid; 00258 int k=0; 00259 00260 00261 /* Fork the acceptor process */ 00262 #ifdef CDP_FOR_SER 00263 pid = fork_process(1000,"cdp_acceptor",1); 00264 #else 00265 pid = fork(); 00266 #endif 00267 if (pid==-1){ 00268 LOG(L_CRIT,"ERROR:init_diameter_peer(): Error on fork() for acceptor!\n"); 00269 return 0; 00270 } 00271 if (pid==0) { 00272 acceptor_process(config); 00273 LOG(L_CRIT,"ERROR:init_diameter_peer(): acceptor_process finished without exit!\n"); 00274 exit(-1); 00275 }else{ 00276 dp_add_pid(pid); 00277 } 00278 00279 /* fork workers */ 00280 for(k=0;k<config->workers;k++){ 00281 #ifdef CDP_FOR_SER 00282 pid = fork_process(1001+k,"cdp_worker",1); 00283 #else 00284 pid = fork(); 00285 #endif 00286 if (pid==-1){ 00287 LOG(L_CRIT,"ERROR:init_diameter_peer(): Error on fork() for worker!\n"); 00288 return 0; 00289 } 00290 if (pid==0) { 00291 srandom(time(0)*k); 00292 #ifdef CDP_FOR_SER 00293 snprintf(pt[process_no].desc, MAX_PT_DESC, 00294 "cdp worker child=%d", k ); 00295 #endif 00296 worker_process(k); 00297 LOG(L_CRIT,"ERROR:init_diameter_peer(): worker_process finished without exit!\n"); 00298 exit(-1); 00299 }else{ 00300 dp_add_pid(pid); 00301 } 00302 } 00303 00304 /* fork/become timer */ 00305 if (blocking) { 00306 dp_add_pid(getpid()); 00307 timer_process(1); 00308 } 00309 else{ 00310 #ifdef CDP_FOR_SER 00311 pid = fork_process(1001,"cdp_timer",1); 00312 #else 00313 pid = fork(); 00314 #endif 00315 if (pid==-1){ 00316 LOG(L_CRIT,"ERROR:init_diameter_peer(): Error on fork() for timer!\n"); 00317 return 0; 00318 } 00319 if (pid==0) { 00320 timer_process(0); 00321 LOG(L_CRIT,"ERROR:init_diameter_peer(): timer_process finished without exit!\n"); 00322 exit(-1); 00323 }else{ 00324 dp_add_pid(pid); 00325 } 00326 } 00327 00328 return 1; 00329 }
| void diameter_peer_destroy | ( | ) |
Shutdown the CDiameterPeer nicely.
It stops the workers, disconnects peers, drops timers and wait for all processes to exit.
Definition at line 337 of file diameter_peer.c.
References config, dp_del_pid(), dp_first_pid, dp_last_pid(), free_dp_config(), handlers, handlers_lock, handler_list_t::head, memlog, handler_t::next, peer_manager_destroy(), pid_list, pid_list_lock, session_destroy(), shutdownx, shutdownx_lock, pid_list_head_t::tail, timer_cdp_destroy(), worker_destroy(), and worker_poison_queue().
Referenced by cdp_exit().
00338 { 00339 int pid,status; 00340 handler *h; 00341 00342 lock_get(shutdownx_lock); 00343 if (*shutdownx) { 00344 /* already other process is cleaning stuff */ 00345 lock_release(shutdownx_lock); 00346 return; 00347 }else { 00348 /* indicating that we are shuting down */ 00349 *shutdownx = 1; 00350 lock_release(shutdownx_lock); 00351 } 00352 00353 00354 worker_poison_queue(); 00355 00356 /* wait for all childs to clean up nicely (acceptor, receiver, timer, workers) */ 00357 LOG(L_INFO,"INFO:destroy_diameter_peer(): Terminating all childs...\n"); 00358 while(pid_list->tail){ 00359 pid = dp_last_pid(); 00360 if (pid<=0||pid==getpid()){ 00361 dp_del_pid(pid); 00362 continue; 00363 } 00364 LOG(L_INFO,"INFO:destroy_diameter_peer(): Waiting for child [%d] to terminate...\n",pid); 00365 if (waitpid(pid,&status,0)<0){ 00366 dp_del_pid(pid); 00367 continue; 00368 } 00369 if (!WIFEXITED(status) /*|| WIFSIGNALED(status)*/){ 00370 worker_poison_queue(); 00371 sleep(1); 00372 } else { 00373 dp_del_pid(pid); 00374 } 00375 00376 } 00377 LOG(L_INFO,"INFO:destroy_diameter_peer(): All processes terminated. Cleaning up.\n"); 00378 00379 /* clean upt the timer */ 00380 timer_cdp_destroy(); 00381 00382 /* cleaning up workers */ 00383 worker_destroy(); 00384 00385 /* cleaning peer_manager */ 00386 peer_manager_destroy(); 00387 00388 /* cleaning up sessions */ 00389 session_destroy(); 00390 00391 /* cleaning up global vars */ 00392 /* lock_get(pid_list_lock);*/ 00393 shm_free(dp_first_pid); 00394 shm_free(pid_list); 00395 lock_destroy(pid_list_lock); 00396 lock_dealloc((void*)pid_list_lock); 00397 00398 shm_free(shutdownx); 00399 00400 lock_destroy(shutdownx_lock); 00401 lock_dealloc((void*)shutdownx_lock); 00402 00403 lock_get(handlers_lock); 00404 while(handlers->head){ 00405 h = handlers->head->next; 00406 shm_free(handlers->head); 00407 handlers->head = h; 00408 } 00409 lock_destroy(handlers_lock); 00410 lock_dealloc((void*)handlers_lock); 00411 shm_free(handlers); 00412 00413 free_dp_config(config); 00414 LOG(L_CRIT,"INFO:destroy_diameter_peer(): Bye Bye from C Diameter Peer test\n"); 00415 00416 #ifndef CDP_FOR_SER 00417 #ifdef PKG_MALLOC 00418 LOG(memlog, "Memory status (pkg):\n"); 00419 //pkg_status(); 00420 #ifdef pkg_sums 00421 pkg_sums(); 00422 #endif 00423 #endif 00424 #ifdef SHM_MEM 00425 LOG(memlog, "Memory status (shm):\n"); 00426 //shm_status(); 00427 #ifdef shm_sums 00428 shm_sums(); 00429 #endif 00430 /* zero all shmem alloc vars that we still use */ 00431 shm_mem_destroy(); 00432 #endif 00433 #endif 00434 }
| int* shutdownx = 0 |
whether a shutdown is in progress
Definition at line 78 of file diameter_peer.c.
Referenced by accept_loop(), cdp_lock_get(), cdp_lock_release(), diameter_peer_destroy(), diameter_peer_init(), put_task(), receive_loop(), select_recv(), take_task(), timer_loop(), and worker_process().
| gen_lock_t* shutdownx_lock |
lock used on shutdown
Definition at line 79 of file diameter_peer.c.
Referenced by diameter_peer_destroy(), and diameter_peer_init().
| pid_t* dp_first_pid |
first pid that we started from
Definition at line 81 of file diameter_peer.c.
Referenced by diameter_peer_destroy(), and diameter_peer_init().
list of local processes
Definition at line 83 of file diameter_peer.c.
Referenced by diameter_peer_destroy(), diameter_peer_init(), dp_add_pid(), dp_del_pid(), and dp_last_pid().
| gen_lock_t* pid_list_lock |
lock for list of local processes
Definition at line 84 of file diameter_peer.c.
Referenced by diameter_peer_destroy(), diameter_peer_init(), dp_add_pid(), dp_del_pid(), and dp_last_pid().
list of handlers
Definition at line 60 of file api_process.c.
Referenced by AAAAddRequestHandler(), AAAAddResponseHandler(), api_callback(), diameter_peer_destroy(), and diameter_peer_init().
| gen_lock_t* handlers_lock |
lock for list of handlers
Definition at line 61 of file api_process.c.
Referenced by AAAAddRequestHandler(), AAAAddResponseHandler(), api_callback(), diameter_peer_destroy(), and diameter_peer_init().
| int memlog |
Referenced by destroy_memory(), diameter_peer_destroy(), init_memory(), receiver_process(), timer_process(), and worker_process().
1.5.2