| 428 | |
| 429 | |
| 430 | int t_handle_async(struct sip_msg *msg, struct action* a, |
| 431 | struct script_route_ref *resume_route, |
| 432 | unsigned int timeout, void **params) |
| 433 | { |
| 434 | async_tm_ctx *ctx = NULL; |
| 435 | struct cell *t; |
| 436 | int r; |
| 437 | int fd = 0; |
| 438 | |
| 439 | /* create transaction and save everything into transaction */ |
| 440 | t=get_t(); |
| 441 | if ( t==0 || t==T_UNDEFINED ) { |
| 442 | /* create transaction */ |
| 443 | r = t_newtran( msg , 1 /*full uas clone*/ ); |
| 444 | if (r==0) { |
| 445 | /* retransmission -> no follow up; we return a negative |
| 446 | * code to indicate do_action that the top route is |
| 447 | * is completed (there no resume route to follow) */ |
| 448 | return -1; |
| 449 | } else if (r<0) { |
| 450 | LM_ERR("could not create a new transaction\n"); |
| 451 | goto failure; |
| 452 | } |
| 453 | t=get_t(); |
| 454 | } else { |
| 455 | /* update the cloned UAS (from transaction) |
| 456 | * with data from current msg */ |
| 457 | if ((t->uas.request) && (route_type==REQUEST_ROUTE)) |
| 458 | update_cloned_msg_from_msg( t->uas.request, msg); |
| 459 | } |
| 460 | |
| 461 | /* run the function (the action) and get back from it the FD, |
| 462 | * resume function and param */ |
| 463 | if ( a->type!=AMODULE_T || a->elem[0].type!=ACMD_ST || |
| 464 | a->elem[0].u.data==NULL ) { |
| 465 | LM_CRIT("BUG - invalid action for async I/O - it must be" |
| 466 | " a MODULE_T ACMD_ST \n"); |
| 467 | goto failure; |
| 468 | } |
| 469 | |
| 470 | if ( (ctx=shm_malloc(sizeof(async_tm_ctx)))==NULL) { |
| 471 | LM_ERR("failed to allocate new ctx\n"); |
| 472 | goto failure; |
| 473 | } |
| 474 | |
| 475 | memset(ctx,0,sizeof(async_tm_ctx)); |
| 476 | ctx->async.timeout_s = timeout; |
| 477 | ctx->parent_ctx_set = profiling_get_ctx(&ctx->parent_ctx); |
| 478 | if (ctx->parent_ctx_set) { |
| 479 | struct timespec ts; |
| 480 | int have_sys = 0; |
| 481 | int have_steady = 0; |
| 482 | if (clock_gettime(CLOCK_REALTIME, &ts) == 0) { |
| 483 | ctx->parent_ctx.start_system_ns = ((uint64_t)ts.tv_sec * 1000000000ULL) + (uint64_t)ts.tv_nsec; |
| 484 | have_sys = 1; |
| 485 | } |
| 486 | if (clock_gettime(CLOCK_MONOTONIC, &ts) == 0) { |
| 487 | ctx->parent_ctx.start_steady_ns = ((uint64_t)ts.tv_sec * 1000000000ULL) + (uint64_t)ts.tv_nsec; |
nothing calls this directly
no test coverage detected