📄 reporter.c
字号:
ReportRoot = reporthdr; Condition_Signal( &ReportCond ); Condition_Unlock( ReportCond );#else // set start time gettimeofday( &(reporthdr->report.startTime), NULL ); /* * Process the report in this thread */ reporthdr->next = NULL; process_report ( reporthdr );#endif } if ( !isDataReport( agent ) ) { reporthdr = NULL; } return reporthdr;}/* * ReportPacket is called by a transfer agent to record * the arrival or departure of a "packet" (for TCP it * will actually represent many packets). This needs to * be as simple and fast as possible as it gets called for * every "packet". */void ReportPacket( ReportHeader* agent, ReportStruct *packet ) { if ( agent != NULL ) { int index = agent->reporterindex; /* * First find the appropriate place to put the information */ if ( agent->agentindex == NUM_REPORT_STRUCTS ) { // Just need to make sure that reporter is not on the first // item while ( index == 0 ) { Condition_Signal( &ReportCond ); thread_rest(); index = agent->reporterindex; } agent->agentindex = 0; } // Need to make sure that reporter is not about to be "lapped" while ( index - 1 == agent->agentindex ) { Condition_Signal( &ReportCond ); thread_rest(); index = agent->reporterindex; } // Put the information there memcpy( agent->data + agent->agentindex, packet, sizeof(ReportStruct) ); // Updating agentindex MUST be the last thing done agent->agentindex++;#ifndef HAVE_THREAD /* * Process the report in this thread */ process_report ( agent );#endif }}/* * CloseReport is called by a transfer agent to finalize * the report and signal transfer is over. */void CloseReport( ReportHeader *agent, ReportStruct *packet ) { if ( agent != NULL) { /* * Using PacketID of -1 ends reporting */ packet->packetID = -1; packet->packetLen = 0; ReportPacket( agent, packet ); packet->packetID = agent->report.cntDatagrams; }}/* * EndReport signifies the agent no longer is interested * in the report. Calls to GetReport will no longer be * filled */void EndReport( ReportHeader *agent ) { if ( agent != NULL ) { int index = agent->reporterindex; while ( index != -1 ) { thread_rest(); index = agent->reporterindex; } agent->agentindex = -1;#ifndef HAVE_THREAD /* * Process the report in this thread */ process_report ( agent );#endif }}/* * GetReport is called by the agent after a CloseReport * but before an EndReport to get the stats generated * by the reporter thread. */Transfer_Info *GetReport( ReportHeader *agent ) { int index = agent->reporterindex; while ( index != -1 ) { thread_rest(); index = agent->reporterindex; } return &agent->report.info;}/* * ReportSettings will generate a summary report for * settings being used with Listeners or Clients */void ReportSettings( thread_Settings *agent ) { if ( isSettingsReport( agent ) ) { /* * Create in one big chunk */ ReportHeader *reporthdr = malloc( sizeof(ReportHeader) ); if ( reporthdr != NULL ) { ReporterData *data = &reporthdr->report; data->info.transferID = agent->mSock; data->info.groupID = -1; reporthdr->agentindex = -1; reporthdr->reporterindex = -1; data->mHost = agent->mHost; data->mLocalhost = agent->mLocalhost; data->mode = agent->mReportMode; data->type = SETTINGS_REPORT; data->mBufLen = agent->mBufLen; data->mMSS = agent->mMSS; data->mTCPWin = agent->mTCPWin; data->flags = agent->flags; data->mThreadMode = agent->mThreadMode; data->mPort = agent->mPort; data->info.mFormat = agent->mFormat; data->info.mTTL = agent->mTTL; data->connection.peer = agent->peer; data->connection.size_peer = agent->size_peer; data->connection.local = agent->local; data->connection.size_local = agent->size_local; #ifdef HAVE_THREAD /* * Update the ReportRoot to include this report. */ Condition_Lock( ReportCond ); reporthdr->next = ReportRoot; ReportRoot = reporthdr; Condition_Signal( &ReportCond ); Condition_Unlock( ReportCond ); #else /* * Process the report in this thread */ reporthdr->next = NULL; process_report ( reporthdr ); #endif } else { FAIL(1, "Out of Memory!!\n", agent); } }}/* * ReportServerUDP will generate a report of the UDP * statistics as reported by the server on the client * side. */void ReportServerUDP( thread_Settings *agent, server_hdr *server ) { if ( (ntohl(server->flags) & HEADER_VERSION1) != 0 && isServerReport( agent ) ) { /* * Create in one big chunk */ ReportHeader *reporthdr = malloc( sizeof(ReportHeader) ); Transfer_Info *stats = &reporthdr->report.info; if ( reporthdr != NULL ) { stats->transferID = agent->mSock; stats->groupID = (agent->multihdr != NULL ? agent->multihdr->groupID : -1); reporthdr->agentindex = -1; reporthdr->reporterindex = -1; reporthdr->report.type = SERVER_RELAY_REPORT; reporthdr->report.mode = agent->mReportMode; stats->mFormat = agent->mFormat; stats->jitter = ntohl( server->jitter1 ); stats->jitter += ntohl( server->jitter2 ) / (double)rMillion; stats->TotalLen = (((max_size_t) ntohl( server->total_len1 )) << 32) + ntohl( server->total_len2 ); stats->startTime = 0; stats->endTime = ntohl( server->stop_sec ); stats->endTime += ntohl( server->stop_usec ) / (double)rMillion; stats->cntError = ntohl( server->error_cnt ); stats->cntOutofOrder = ntohl( server->outorder_cnt ); stats->cntDatagrams = ntohl( server->datagrams ); stats->mUDP = (char)kMode_Server; reporthdr->report.connection.peer = agent->local; reporthdr->report.connection.size_peer = agent->size_local; reporthdr->report.connection.local = agent->peer; reporthdr->report.connection.size_local = agent->size_peer; #ifdef HAVE_THREAD /* * Update the ReportRoot to include this report. */ Condition_Lock( ReportCond ); reporthdr->next = ReportRoot; ReportRoot = reporthdr; Condition_Signal( &ReportCond ); Condition_Unlock( ReportCond );#else /* * Process the report in this thread */ reporthdr->next = NULL; process_report ( reporthdr );#endif } else { FAIL(1, "Out of Memory!!\n", agent); } }}/* * This function is called only when the reporter thread * This function is the loop that the reporter thread processes */void reporter_spawn( thread_Settings *thread ) { do { // This section allows for safe exiting with Ctrl-C Condition_Lock ( ReportCond ); if ( ReportRoot == NULL ) { // Allow main thread to exit if Ctrl-C is received thread_setignore(); Condition_Wait ( &ReportCond ); // Stop main thread from exiting until done with all reports thread_unsetignore(); } Condition_Unlock ( ReportCond ); if ( ReportRoot != NULL ) { ReportHeader *temp = ReportRoot; //Condition_Unlock ( ReportCond ); if ( reporter_process_report ( temp ) ) { // This section allows for more reports to be added while // the reporter is processing reports without needing to // stop the reporter or immediately notify it Condition_Lock ( ReportCond ); if ( temp == ReportRoot ) { // no new reports ReportRoot = temp->next; } else { // new reports added ReportHeader *itr = ReportRoot; while ( itr->next != temp ) { itr = itr->next; } itr->next = temp->next; } // finished with report so free it free( temp ); Condition_Unlock ( ReportCond ); } // yield control of CPU is another thread is waiting thread_rest(); } else { //Condition_Unlock ( ReportCond ); } } while ( 1 );}/* * Used for single threaded reporting */void process_report ( ReportHeader *report ) { if ( report != NULL ) { if ( reporter_process_report( report ) ) { free( report ); } }}/* * Process reports starting with "reporthdr" */int reporter_process_report ( ReportHeader *reporthdr ) { int need_free = 0; // Recursively process reports if ( reporthdr->next != NULL ) { if ( reporter_process_report( reporthdr->next ) ) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -