int main(int argc, char **argv) #endif { int err = 0; pthread_t streamer_pthread; #if(DAEMON) struct opt_s *opt = (struct opt_s *)opti; D("Starting thread from daemon"); #else LOG("Running in non-daemon mode\n"); struct opt_s *opt = malloc(sizeof(struct opt_s)); CHECK_ERR_NONNULL(opt, "opt malloc"); LOG("STREAMER: Reading parameters\n"); clear_and_default(opt, 1); err = parse_options(argc, argv, opt); if (err != 0) STREAMER_ERROR_EXIT; err = init_branches(opt); CHECK_ERR("init branches"); err = init_recp(opt); CHECK_ERR("init recpoints"); #ifdef HAVE_LIBCONFIG_H err = init_cfg(opt); //TODO: cfg destruction if (err != 0) { E("Error in cfg init"); STREAMER_ERROR_EXIT; } #endif //HAVE_LIBCONFIG_H err = init_rbufs(opt); CHECK_ERR("init rbufs"); #endif //DAEMON /* Check and set cfgs at this point */ //return -1; /* If we're sending stuff, check all the diskbranch members for the files they have */ /* Also updates the fileholders list to point the owners of files to correct drives */ #ifdef HAVE_LIBCONFIG_H if (opt->optbits & READMODE) { oper_to_all(opt->diskbranch, BRANCHOP_CHECK_FILES, (void *)opt); LOG ("For recording %s: %lu files were found out of %lu total. file index shows %ld files\n", opt->filename, opt->cumul_found, opt->cumul, afi_get_n_files(opt->fi)); } #endif //HAVE_LIBCONFIG_H /* Handle hostname etc */ /* TODO: Whats the best way that accepts any format? */ err = prep_streamer(opt); if (err != 0) { STREAMER_ERROR_EXIT; } if (opt->optbits & READMODE) LOG("STREAMER: In main, starting sending thread \n"); else LOG("STREAMER: In main, starting receiver thread \n"); #ifdef HAVE_LRT /* TCP streams start counting from accept and others from here */ if (!(opt->optbits & (CAPTURE_W_TCPSPLICE | CAPTURE_W_TCPSTREAM))) GETTIME(opt->starting_time); set_status_for_opt(opt, STATUS_RUNNING); err = pthread_create(&streamer_pthread, NULL, opt->streamer_ent->start, (void *)opt->streamer_ent); if (err != 0) { printf("ERROR; return code from pthread_create() is %d\n", err); STREAMER_ERROR_EXIT; } /* Other thread spawned so we can minimize our priority */ minimize_priority(); #ifdef TUNE_AFFINITY /* Caused some weird ass bugs and crashes so not used anymore NEVER */ /* Put the capture on the first core */ CPU_SET(0, &(opt->cpuset)); err = pthread_setaffinity_np(streamer_pthread, sizeof(cpu_set_t), &cpuset); if (err != 0) { E("Error: setting affinity: %d", err); } CPU_ZERO(&cpuset); #endif #endif { /* READMODE shuts itself down so we just go to pthread_join */ /* Check also that last_packet is 0. Else the thread should shut itself */ /* down */ if (!(opt->optbits & READMODE) && opt->last_packet == 0 && !(opt-> optbits & (CAPTURE_W_TCPSPLICE | CAPTURE_W_TCPSTREAM | CAPTURE_W_MULTISTREAM))) { TIMERTYPE now; GETTIME(now); while ((GETSECONDS(now) <= (GETSECONDS(opt->starting_time) + (long)opt->time)) && get_status_from_opt(opt) == STATUS_RUNNING) { sleep(1); GETTIME(now); } shutdown_thread(opt); pthread_mutex_lock(&(opt->membranch->branchlock)); pthread_cond_broadcast(&(opt->membranch->busysignal)); pthread_mutex_unlock(&(opt->membranch->branchlock)); } } err = pthread_join(streamer_pthread, NULL); if (err < 0) { printf("ERROR; return code from pthread_join() is %d\n", err); } else D("Streamer thread exit OK"); LOG("STREAMER: Threads finished. Getting stats for %s\n", opt->filename); GETTIME(opt->endtime); LOG("Blocking until owned buffers are released\n"); block_until_free(opt->membranch, opt); #if(DAEMON) LOG("Buffers finished\n"); if (get_status_from_opt(opt) != STATUS_STOPPED) { E("Thread didnt finish nicely with STATUS_STOPPED"); set_status_for_opt(opt, STATUS_FINISHED); } else set_status_for_opt(opt, STATUS_FINISHED); #else close_streamer(opt); #endif #if(DAEMON) D("Streamer thread exiting for %s", opt->filename); pthread_exit(NULL); #else close_opts(opt); STREAMER_EXIT; #endif }
struct cell* build_cell( struct sip_msg* p_msg ) { struct cell* new_cell; int sip_msg_len; avp_list_t* old; /* allocs a new cell */ new_cell = (struct cell*)shm_malloc( sizeof( struct cell ) ); if ( !new_cell ) { ser_error=E_OUT_OF_MEM; return NULL; } /* filling with 0 */ memset( new_cell, 0, sizeof( struct cell ) ); /* UAS */ new_cell->uas.response.my_T=new_cell; init_rb_timers(&new_cell->uas.response); /* timers */ init_cell_timers(new_cell); old = set_avp_list(AVP_TRACK_FROM | AVP_CLASS_URI, &new_cell->uri_avps_from ); new_cell->uri_avps_from = *old; *old = 0; old = set_avp_list(AVP_TRACK_TO | AVP_CLASS_URI, &new_cell->uri_avps_to ); new_cell->uri_avps_to = *old; *old = 0; old = set_avp_list(AVP_TRACK_FROM | AVP_CLASS_USER, &new_cell->user_avps_from ); new_cell->user_avps_from = *old; *old = 0; old = set_avp_list(AVP_TRACK_TO | AVP_CLASS_USER, &new_cell->user_avps_to ); new_cell->user_avps_to = *old; *old = 0; /* We can just store pointer to domain avps in the transaction context, * because they are read-only */ new_cell->domain_avps_from = get_avp_list(AVP_TRACK_FROM | AVP_CLASS_DOMAIN); new_cell->domain_avps_to = get_avp_list(AVP_TRACK_TO | AVP_CLASS_DOMAIN); /* enter callback, which may potentially want to parse some stuff, * before the request is shmem-ized */ if ( p_msg && has_reqin_tmcbs() ) run_reqin_callbacks( new_cell, p_msg, p_msg->REQ_METHOD); if (p_msg) { /* clean possible previous added vias/clen header or else they would * get propagated in the failure routes */ free_via_clen_lump(&p_msg->add_rm); new_cell->uas.request = sip_msg_cloner(p_msg,&sip_msg_len); if (!new_cell->uas.request) goto error; new_cell->uas.end_request=((char*)new_cell->uas.request)+sip_msg_len; } /* UAC */ init_branches(new_cell); new_cell->relayed_reply_branch = -1; /* new_cell->T_canceled = T_UNDEFINED; */ init_synonym_id(new_cell); init_cell_lock( new_cell ); return new_cell; error: destroy_avp_list(&new_cell->user_avps_from); destroy_avp_list(&new_cell->user_avps_to); destroy_avp_list(&new_cell->uri_avps_from); destroy_avp_list(&new_cell->uri_avps_to); shm_free(new_cell); /* unlink transaction AVP list and link back the global AVP list (bogdan)*/ reset_avps(); return NULL; }