DEFINE_CONSTRUCTOR_END

/**
* @brief   simulate class CCycbuffer destructor
*
* free all the simulate class member variable,
* @author hankejia
* @date 2012-07-05
* @param[in] pthis   the pointer point to the CCycBuffer.
* @return NONE
*/
DEFINE_DESTRUCTOR_BEGIN( CCycBuffer )
{
    CCycBuffer *this = (CCycBuffer *)pthis;
    CycBuffer_handle * handle = (CycBuffer_handle *)this->handle;

    //虚构时,如果当前还有线程在Push流程中等待
    //那么首先Pop出Buffer中的所有数据,唤醒在Push
    //中等待的线程,等待其完成push操作。
    Condition_Lock( handle->mDataCon );
    if ( !( handle->mPushComplete ) ) {
        Condition_Unlock( handle->mDataCon );
        Clean( this );

        //唤醒在Push中等待的线程
        Condition_Signal( &(handle->mDataCon) );

        Condition_Wait( &(handle->mDataCon) );
        Condition_Unlock( handle->mDataCon );
    } else
        Condition_Unlock( handle->mDataCon );

    //如果当前还有线程在pop流程中等待,那么首先
    //向Buffer中Push数据,唤醒在Pop中等待的线程,等
    //待其完成pop操作。
    Condition_Lock( handle->mDataCon );
    if ( !( handle->mPopComplete ) ) {
        Condition_Unlock( handle->mDataCon );
        FakePushFull( this );

        //唤醒在Pop中等待的线程
        Condition_Signal( &(handle->mDataCon) );

        Condition_Wait( &handle->mDataCon );
        Condition_Unlock( handle->mDataCon );
    } else
        Condition_Unlock( handle->mDataCon );

    DestroyCycBuffer( this );
    Condition_Destroy( &( handle->mDataCon ) );
    Condition_Destroy( &( handle->mWriteDataCon ) );
    //Condition_Destroy( &( handle->mWaitForPopCon ) );
    //Condition_Destroy( &( handle->mWaitForPushCon ) );

    free( handle );
}
Exemple #2
0
/*
 * 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 );

again:
        if ( ReportRoot != NULL ) {
            ReportHeader *temp = ReportRoot;
            //Condition_Unlock ( ReportCond );
            if(temp->report.mThreadMode == kMode_Client){
            	synchronize();
            }
            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 );
                Condition_Signal( &ReportDoneCond );
                if (ReportRoot)
                    goto again;
            }
            Condition_Signal( &ReportDoneCond );
            usleep(10000);
        } else {
            //Condition_Unlock ( ReportCond );
        }
    } while ( 1 );
}
Exemple #3
0
int photograph( void *pbuf, int size)
{

	unsigned long outsize;
	int ret;

	VideoStream_Enc_Reset();
	
	//printf("%d\n", h_eid);
	void * buf;
	if( 2 == index_file )
		ret = frame_encode(h_eid , pbuf+(parse.width*parse.height*3/2), &buf, &outsize);
	else
		ret = frame_encode(h_eid, pbuf, &buf, &outsize);

	if(ret == 0)
	{
		Condition_Lock( g_conMangerPh );
		g_phsize = outsize;
		Condition_Signal( &g_conMangerPh );
		Condition_Unlock( g_conMangerPh );
	}

	VideoStream_Enc_Reset();
	
	return 0;
}
Exemple #4
0
/*
 * 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 = (ReportHeader *) 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;
#ifdef HAVE_INT64_T
            stats->TotalLen = (((max_size_t) ntohl( server->total_len1 )) << 32) +
                                  ntohl( server->total_len2 );
#else
            stats->TotalLen = ntohl( server->total_len2 );
#endif
            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);
        }
    }
}
/* -------------------------------------------------------------------
 * unset a thread from being ignorable, so joinall will wait on it
 * this simply increments the thread count that joinall uses.
 * This is utilized by the reporter thread which knows when it
 * is ok to quit (aka no pending reports).
 * ------------------------------------------------------------------- */
void thread_unsetignore( void ) {
    Condition_Lock( thread_sNum_cond );
    IPERF_DEBUGF( THREAD_DEBUG | IPERF_DBG_TRACE, ( "Unsetting ignorable thread.\r\n" ) );
    thread_sNum++;
    IPERF_DEBUGF( CONDITION_DEBUG | IPERF_DBG_TRACE, ( "Signaling thread_sNum_cond condition.\r\n" ) );
    Condition_Signal( &thread_sNum_cond );
    Condition_Unlock( thread_sNum_cond );
} // end thread_unsetignore
/**
* @brief   write cyc buffer is data to file
*
* @author hankejia
* @date 2012-07-05
* @param[in] pthis			the pointer point to the CCycBuffer.
* @param[in] fd			file is descriptor.the cyc buffer is data will write to this file
* @param[in] iSize			how many data in bytes from cyc buffer you want to write to the file
* @param[in] pWriteBuffer	the space alloc by caller,fuction will use this space to load the data,and write to file system,
*						if this param is NULL, function will alloc space by himself
* @return T_S32
* @retval return  >=0 the size of bytes write to file, < 0  failed
*/
static T_S32 WriteToFs( T_pVOID pthis, T_S32 fd, T_S32 iSize )
{
    CCycBuffer *this = ( CCycBuffer * )pthis;
    CycBuffer_handle * handle = (CycBuffer_handle *)this->handle;
    T_CHR * pBuffer = NULL;
    T_S32 iLineSize = 0, iLeavings = 0;

    Condition_Lock( handle->mWriteDataCon );

    //need to flash all data
    if ( -1 == iSize ) {
        iSize = handle->mUseSize;
    }

    pBuffer = PopSingle( pthis, iSize );

    if ( pBuffer == NULL ) {
        ResumeForceQuitState( pthis );
        Condition_Unlock( handle->mWriteDataCon );
        delay_loop( 0, 10000 ); // 10ms
        return 0;
    }

    iLeavings = iSize;

    while( iLeavings > 0 ) {
        iLineSize = ( handle->mCycBuffer + handle->mBufferSize ) - pBuffer;
        if ( iLineSize == 0 ) {
            pBuffer = handle->mCycBuffer;
            continue;
        } else if ( iLineSize > iLeavings ) {
            iLineSize = iLeavings;
        }

        if ( WriteComplete( fd, pBuffer, iLineSize ) < 0 ) {
            Condition_Unlock( handle->mWriteDataCon );
            loge( "WriteToFs::WriteComplete error!\n" );
            return -1;
        }

        pBuffer += iLineSize;
        iLeavings -= iLineSize;
    }

    Condition_Lock( handle->mDataCon );
    handle->mRead = pBuffer;
    handle->mUseSize -= iSize;
    handle->mPopComplete = AK_TRUE;
    Condition_Unlock( handle->mDataCon );
    Condition_Unlock( handle->mWriteDataCon );

    //logi( "pop signal send!\n" );
    Condition_Signal( &(handle->mDataCon) );

    return iSize;
}
Exemple #7
0
/* -------------------------------------------------------------------
 * this function releases all non-terminating threads from the list
 * of active threads, so that when all terminating threads quit
 * the joinall will complete. This is called on a Ctrl-C input. It is
 * also used by the -P usage on the server side
 * ------------------------------------------------------------------- */
int thread_release_nonterm( int interrupt ) {
    Condition_Lock( thread_sNum_cond );
    thread_sNum -= nonterminating_num;
    if ( thread_sNum > 1 && nonterminating_num > 0 && interrupt != 0 ) {
        fprintf( stderr,"%s", wait_server_threads );
    }
    nonterminating_num = 0;
    Condition_Signal( &thread_sNum_cond );
    Condition_Unlock( thread_sNum_cond );
    return thread_sNum;
}
Exemple #8
0
/*
 * 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;
            data->mUDPRate = agent->mUDPRate;
            data->mUDPRateUnits = agent->mUDPRateUnits;
    #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);
        }
    }
}
Exemple #9
0
/*
 * 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 );
                Condition_Lock( ReportCond );
                Condition_Wait( &ReportDoneCond );
                Condition_Unlock( ReportCond );
                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 );
            Condition_Lock( ReportCond );
            Condition_Wait( &ReportDoneCond );
            Condition_Unlock( ReportCond );
            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 
    }
}
/* -------------------------------------------------------------------
 * this function releases all non-terminating threads from the list
 * of active threads, so that when all terminating threads quit
 * the joinall will complete. This is called on a Ctrl-C input. It is
 * also used by the -P usage on the server side
 * ------------------------------------------------------------------- */
int thread_release_nonterm( int interrupt ) {
    Condition_Lock( thread_sNum_cond );
    IPERF_DEBUGF( THREAD_DEBUG | IPERF_DBG_TRACE, ( "Releasing all non-terminating threads.\r\n" ) );
    thread_sNum -= nonterminating_num;
    if ( thread_sNum > 1 && nonterminating_num > 0 && interrupt != 0 ) {
        fprintf( stderr, "%s", wait_server_threads );
    }
    nonterminating_num = 0;
    IPERF_DEBUGF( CONDITION_DEBUG | IPERF_DBG_TRACE, ( "Signaling thread_sNum_cond condition.\r\n" ) );
    Condition_Signal( &thread_sNum_cond );
    Condition_Unlock( thread_sNum_cond );
    return thread_sNum;
} // end thread_release_nonterm
/* -------------------------------------------------------------------
 * Stop the specified object's thread execution (if any) immediately.
 * Decrements thread count and resets the thread ID.
 * ------------------------------------------------------------------- */
void thread_stop( struct thread_Settings* thread ) {
#ifdef HAVE_THREAD
    // Make sure we have been started
    if ( ! thread_equalid( thread->mTID, thread_zeroid() ) ) {
        // decrement thread count
        Condition_Lock( thread_sNum_cond );
        IPERF_DEBUGF( THREAD_DEBUG | IPERF_DBG_TRACE, ( "Decrementing thread count from %d to %d.\r\n", thread_sNum, (thread_sNum - 1) ) );
        thread_sNum--;
        IPERF_DEBUGF( CONDITION_DEBUG | IPERF_DBG_TRACE, ( "Signaling thread_sNum_cond condition.\r\n" ) );
        Condition_Signal( &thread_sNum_cond );
        Condition_Unlock( thread_sNum_cond );

        // use exit()   if called from within this thread
        // use cancel() if called from a different thread
        if ( thread_equalid( thread_getid(), thread->mTID ) ) {
            // Destroy the object
            Settings_Destroy( thread );

            // Exit
#if   defined( HAVE_POSIX_THREAD )
            IPERF_DEBUGF( THREAD_DEBUG | IPERF_DBG_TRACE, ( "Exiting %s thread.\r\n", thread_names[thread->mThreadMode] ) );
            pthread_exit( NULL );
#elif defined( HAVE_WIN32_THREAD )
            IPERF_DEBUGF( THREAD_DEBUG | IPERF_DBG_TRACE, ( "Exiting %s thread.\r\n", thread_names[thread->mThreadMode] ) );
            CloseHandle( thread->mHandle );
            ExitThread( 0 );
#endif /* HAVE_POSIX_THREAD */
        } else {
            // Cancel
#if   defined( HAVE_POSIX_THREAD )
            // Cray J90 doesn't have pthread_cancel; Iperf works okay without
#ifdef HAVE_PTHREAD_CANCEL
            IPERF_DEBUGF( THREAD_DEBUG | IPERF_DBG_TRACE, ( "Canceling %s thread.\r\n", thread_names[thread->mThreadMode] ) );
            pthread_cancel( thread->mTID );
#endif /* HAVE_PTHREAD_CANCEL */
#elif defined(HAVE_WIN32_THREAD)
            // this is a somewhat dangerous function; it's not
            // suggested to Stop() threads a lot.
            IPERF_DEBUGF( THREAD_DEBUG | IPERF_DBG_TRACE, ( "Terminating %s thread.\r\n", thread_names[thread->mThreadMode] ) );
            TerminateThread( thread->mHandle, 0 );
#endif /* HAVE_POSIX_THREAD */

            // Destroy the object only after killing the thread
            Settings_Destroy( thread );
        }
    }
#endif /* HAVE_THREAD */
} // end thread_stop
Exemple #12
0
/* -------------------------------------------------------------------
 * Stop the specified object's thread execution (if any) immediately.
 * Decrements thread count and resets the thread ID.
 * ------------------------------------------------------------------- */
void thread_stop( struct thread_Settings* thread ) {

#ifdef HAVE_THREAD
    // Make sure we have been started
    if ( ! thread_equalid( thread->mTID, thread_zeroid() ) ) {

        // decrement thread count
        Condition_Lock( thread_sNum_cond );
        thread_sNum--;
        Condition_Signal( &thread_sNum_cond );
        Condition_Unlock( thread_sNum_cond );

        // use exit()   if called from within this thread
        // use cancel() if called from a different thread
        if ( thread_equalid( thread_getid(), thread->mTID ) ) {

            // Destroy the object
            Settings_Destroy( thread );

            // Exit
#if   defined( HAVE_POSIX_THREAD )
            pthread_exit( NULL );
#else // Win32
            CloseHandle( thread->mHandle );
            ExitThread( 0 );
#endif
        } else {

            // Cancel
#if   defined( HAVE_POSIX_THREAD )
            // Cray J90 doesn't have pthread_cancel; Iperf works okay without
#ifdef HAVE_PTHREAD_CANCEL
            pthread_cancel( thread->mTID );
#endif
#else // Win32
            // this is a somewhat dangerous function; it's not
            // suggested to Stop() threads a lot.
            TerminateThread( thread->mHandle, 0 );
#endif

            // Destroy the object only after killing the thread
            Settings_Destroy( thread );
        }
    }
#endif
} // end Stop
Exemple #13
0
/* -------------------------------------------------------------------
 * unset a thread from being ignorable, so joinall will wait on it
 * this simply increments the thread count that joinall uses.
 * This is utilized by the reporter thread which knows when it
 * is ok to quit (aka no pending reports).
 * ------------------------------------------------------------------- */
void thread_unsetignore( void ) {
    Condition_Lock( thread_sNum_cond );
    thread_sNum++;
    Condition_Signal( &thread_sNum_cond );
    Condition_Unlock( thread_sNum_cond );
}
Exemple #14
0
/* -------------------------------------------------------------------
 * set a thread to be ignorable, so joinall won't wait on it
 * this simply decrements the thread count that joinall uses.
 * This is utilized by the reporter thread which knows when it
 * is ok to quit (aka no pending reports).
 * ------------------------------------------------------------------- */
void thread_setignore( ) {
    Condition_Lock( thread_sNum_cond );
    thread_sNum--;
    Condition_Signal( &thread_sNum_cond );
    Condition_Unlock( thread_sNum_cond );
}
Exemple #15
0
DWORD WINAPI
#else
void*
#endif
thread_run_wrapper( void* paramPtr ) {
    struct thread_Settings* thread = (struct thread_Settings*) paramPtr;

    // which type of object are we
    switch ( thread->mThreadMode ) {
        case kMode_Server:
            {
                /* Spawn a Server thread with these settings */
                server_spawn( thread );
            } break;
        case kMode_Client:
            {
                /* Spawn a Client thread with these settings */
                client_spawn( thread );
            } break;
        case kMode_Reporter:
            {
                /* Spawn a Reporter thread with these settings */
                reporter_spawn( thread );
            } break;
        case kMode_Listener:
            {
                // Increment the non-terminating thread count
                thread_register_nonterm();
                /* Spawn a Listener thread with these settings */
                listener_spawn( thread );
                // Decrement the non-terminating thread count
                thread_unregister_nonterm();
            } break;
        default:
            {
                FAIL(1, "Unknown Thread Type!\n", thread);
            } break;
    }

#ifdef HAVE_POSIX_THREAD
    // detach Thread. If someone already joined it will not do anything
    // If noone has then it will free resources upon return from this
    // function (Run_Wrapper)
    pthread_detach(thread->mTID);
#endif

    // decrement thread count and send condition signal
    Condition_Lock( thread_sNum_cond );
    thread_sNum--;
    Condition_Signal( &thread_sNum_cond );
    Condition_Unlock( thread_sNum_cond );

    // Check if we need to start up a thread after executing this one
    if ( thread->runNext != NULL ) {
        thread_start( thread->runNext );
    }

    // Destroy this thread object
    Settings_Destroy( thread );

    return 0;
} // end run_wrapper
DWORD WINAPI
#else
void*
#endif /* HAVE_WIN32_THREAD */
thread_run_wrapper( void* paramPtr ) {
    struct thread_Settings* thread = (struct thread_Settings*) paramPtr;
    IPERF_DEBUGF( THREAD_DEBUG | IPERF_DBG_TRACE | IPERF_DBG_STATE, ( "%s thread is now running. ID is %lu.\r\n", thread_names[thread->mThreadMode], (long unsigned) thread_getid() ) );

    // which type of object are we
    switch ( thread->mThreadMode ) {
        case kMode_Server:
            {
                /* Spawn a Server thread with these settings */
                server_spawn( thread );
            } break;
        case kMode_Client:
            {
                /* Spawn a Client thread with these settings */
                client_spawn( thread );
            } break;
        case kMode_Reporter:
            {
                /* Spawn a Reporter thread with these settings */
                reporter_spawn( thread );
            } break;
        case kMode_Listener:
            {
                // Increment the non-terminating thread count
                thread_register_nonterm();
                /* Spawn a Listener thread with these settings */
                listener_spawn( thread );
                // Decrement the non-terminating thread count
                thread_unregister_nonterm();
            } break;
        default:
            {
                FAIL(1, ( "Unknown Thread Type!\r\n" ), thread);
            } break;
    }

#ifdef HAVE_POSIX_THREAD
    // detach Thread. If someone already joined it will not do anything
    // If noone has then it will free resources upon return from this
    // function (Run_Wrapper)
    IPERF_DEBUGF( THREAD_DEBUG | IPERF_DBG_TRACE, ( "Detaching %s thread.\r\n", thread_names[thread->mThreadMode] ) );
    pthread_detach(thread->mTID);
#endif /* HAVE_POSIX_THREAD */

    // decrement thread count and send condition signal
    Condition_Lock( thread_sNum_cond );
    IPERF_DEBUGF( THREAD_DEBUG | IPERF_DBG_TRACE, ( "Decrementing thread count from %d to %d.\r\n", thread_sNum, (thread_sNum - 1) ) );
    thread_sNum--;

    IPERF_DEBUGF( CONDITION_DEBUG | IPERF_DBG_TRACE, ( "Signaling thread_sNum_cond condition.\r\n" ) );
    Condition_Signal( &thread_sNum_cond );
    Condition_Unlock( thread_sNum_cond );

    // Check if we need to start up a thread after executing this one
    if ( thread->runNext != NULL ) {
        thread_start( thread->runNext );
    }

    // Destroy this thread object
    Settings_Destroy( thread );

    return 0;
} // end thread_run_wrapper
Exemple #17
0
static T_S32 PushSingle( T_pVOID pthis, T_CHR * pBuffer, T_S32 iSize )
{
    CCycBuffer *this = ( CCycBuffer * )pthis;
    CycBuffer_handle * handle = (CycBuffer_handle *)this->handle;
    T_S32 iLeavings = 0;
    T_S32 iWriteSize = 0;
    T_S32 iLineSize = 0;
    T_CHR *	mTempWrite = NULL;

    if ( iSize > handle->mBufferSize ) {
        loge( "CCycBuffer::Push() can't not push %d data to buffer, %d > %d(buffer size)", iSize, iSize, handle->mBufferSize );
        return -1;
    }

    //the cyc buffer is full. wait for pop
    Condition_Lock( handle->mDataCon );
    handle->mPushComplete = AK_FALSE;
    while ( ( ( handle->mBufferSize - handle->mUseSize ) < iSize ) &&
            ( !(handle->mForceQuit) ) ) {
        //Condition_Unlock( handle->mDataCon );
        logi( "PushSingle buffer full! %d\n", handle->mBufferSize );
        Condition_Wait( &(handle->mDataCon) );
        //logi( "wake up from pop signed!\n" );
        //Condition_Lock( handle->mDataCon );
    }

    if ( handle->mForceQuit ) {
        handle->mPushComplete = AK_TRUE;
        Condition_Unlock( handle->mDataCon );
        return 0;
    }

    assert( ( pBuffer != NULL ) && ( handle->mCycBuffer != NULL ) && ( iSize > 0 ) );
    assert( ( ( handle->mRead >= handle->mCycBuffer ) && ( handle->mRead < (handle->mCycBuffer + handle->mBufferSize) ) ) );
    assert( ( ( handle->mWrite >= handle->mCycBuffer ) && ( handle->mWrite < (handle->mCycBuffer + handle->mBufferSize) ) ) );

    mTempWrite = handle->mWrite;
    Condition_Unlock( handle->mDataCon );

    iLeavings = iSize;

    while ( iLeavings > 0 )
    {
        iLineSize = ( handle->mCycBuffer + handle->mBufferSize ) - mTempWrite;
        iWriteSize = ( iLineSize > iLeavings )?iLeavings:iLineSize;
        memcpy( mTempWrite, pBuffer, iWriteSize );

        if ( iWriteSize == iLineSize )
            mTempWrite = handle->mCycBuffer;
        else
            mTempWrite += iWriteSize;

        pBuffer += iWriteSize;
        iLeavings -= iWriteSize;
    }

    Condition_Lock( handle->mDataCon );
    handle->mWrite = mTempWrite;
    handle->mUseSize = ( ( handle->mUseSize + iSize ) > handle->mBufferSize )?handle->mBufferSize:( handle->mUseSize + iSize );
    if ( handle->mUseSize == handle->mBufferSize )
        handle->mRead = handle->mWrite;

    handle->mPushComplete = AK_TRUE;

    Condition_Unlock( handle->mDataCon );

    Condition_Signal( &(handle->mDataCon) );
    return iSize;
}
Exemple #18
0
/**
* @brief   pop data from cyc buffer
*
* @author hankejia
* @date 2012-07-05
* @param[in] pthis		the pointer point to the CCycBuffer.
* @param[out] pBuffer	the memory to saved the data
* @param[in] iSize		how many bytes you want to pop from cyc buffer
* @return T_S32
* @retval return  >=0 the size of bytes pop from cyc buffer, < 0  failed
*/
static T_S32 Pop( T_pVOID pthis, char * pBuffer, T_S32 iSize )
{
    CCycBuffer *this = ( CCycBuffer * )pthis;
    CycBuffer_handle * handle = (CycBuffer_handle *)this->handle;
    T_S32 iGetSize= 0;
    T_S32 iLeavings = 0;
    T_S32 iReadSize = 0;
    T_S32 iLineSize = 0;

    if ( iSize > handle->mBufferSize ) {
        loge( "CCycBuffer::Pop() can't not Pop %d data from buffer, %d > %d(buffer size)", iSize, iSize, handle->mBufferSize );
        return -1;
    }

    //the cyc buffer is empty, wait for push
    Condition_Lock( handle->mDataCon );
    handle->mPopComplete = AK_FALSE;
    while ( ( handle->mUseSize < iSize ) && ( !(handle->mForceQuit) ) ) {
        //Condition_Unlock( handle->mDataCon );
        //logi( "buffer empty!\n" );
        Condition_Wait( &(handle->mDataCon) );
        //logi( "wake up from push signed!\n" );
        //Condition_Lock( handle->mDataCon );
    }

    if ( handle->mForceQuit ) {
        handle->mPopComplete = AK_TRUE;
        Condition_Unlock( handle->mDataCon );
        return 0;
    }

    assert( ( pBuffer != NULL ) && ( handle->mCycBuffer != NULL ) && ( iSize > 0 ) );
    assert( ( ( handle->mRead >= handle->mCycBuffer ) && ( handle->mRead < (handle->mCycBuffer + handle->mBufferSize) ) ) );
    assert( ( ( handle->mWrite >= handle->mCycBuffer ) && ( handle->mWrite < (handle->mCycBuffer + handle->mBufferSize) ) ) );

    iGetSize = ( (handle->mUseSize) > iSize )?iSize:(handle->mUseSize);
    iLeavings = iGetSize;

    while ( iLeavings > 0 )
    {
        iLineSize = ( handle->mCycBuffer + handle->mBufferSize ) - handle->mRead;
        iReadSize = ( iLineSize > iLeavings )?iLeavings:iLineSize;
        memcpy( pBuffer, handle->mRead, iReadSize );

        if ( iReadSize == iLineSize )
            handle->mRead = handle->mCycBuffer;
        else
            handle->mRead += iReadSize;

        pBuffer += iReadSize;
        iLeavings -= iReadSize;
    }

    handle->mUseSize -= iGetSize;

    handle->mPopComplete = AK_TRUE;
    Condition_Unlock( handle->mDataCon );

    //logi( "pop signal send!\n" );
    Condition_Signal( &(handle->mDataCon) );

    return iGetSize;
}
Exemple #19
0
/*
 * InitReport is called by a transfer agent (client or
 * server) to setup the needed structures to communicate
 * traffic.
 */
ReportHeader* InitReport( thread_Settings *agent ) {
    ReportHeader *reporthdr = NULL;
    ReporterData *data = NULL;
    if ( isDataReport( agent ) ) {
        /*
         * Create in one big chunk
         */
        reporthdr = malloc( sizeof(ReportHeader) +
                            NUM_REPORT_STRUCTS * sizeof(ReportStruct) );
        if ( reporthdr != NULL ) {
            // Only need to make sure the headers are clean
            memset( reporthdr, 0, sizeof(ReportHeader));
            reporthdr->data = (ReportStruct*)(reporthdr+1);
            reporthdr->multireport = agent->multihdr;
            data = &reporthdr->report;
            reporthdr->reporterindex = NUM_REPORT_STRUCTS - 1;
            data->info.transferID = agent->mSock;
            data->info.groupID = (agent->multihdr != NULL ? agent->multihdr->groupID : 128);
            data->type = TRANSFER_REPORT;
            if ( agent->mInterval != 0.0 ) {
                struct timeval *interval = &data->intervalTime;
                interval->tv_sec = (long) agent->mInterval;
                interval->tv_usec = (long) ((agent->mInterval - interval->tv_sec) * rMillion);
            }
            data->mHost = agent->mHost;
            data->mLocalhost = agent->mLocalhost;
            data->mBufLen = agent->mBufLen;
            data->mMSS = agent->mMSS;
            data->mTCPWin = agent->mTCPWin;
            data->flags = agent->flags;
            data->mThreadMode = agent->mThreadMode;
            data->mode = agent->mReportMode;
            data->info.mFormat = agent->mFormat;
            data->info.mTTL = agent->mTTL;
	    if (data->mThreadMode == kMode_Server) 
		data->info.tcp.read.binsize = data->mBufLen / 8;
            if ( isUDP( agent ) ) {
		gettimeofday(&data->IPGstart, NULL);
                reporthdr->report.info.mUDP = (char)agent->mThreadMode;
            } else {
                reporthdr->report.info.mTCP = (char)agent->mThreadMode;
	    }
	    if ( isEnhanced( agent ) ) {
		data->info.mEnhanced = 1;
	    } else {
		data->info.mEnhanced = 0;
	    }
        } else {
            FAIL(1, "Out of Memory!!\n", agent);
        }
    }
    if ( isConnectionReport( agent ) ) {
        if ( reporthdr == NULL ) {
            /*
             * Create in one big chunk
             */
            reporthdr = malloc( sizeof(ReportHeader) );
            if ( reporthdr != NULL ) {
                // Only need to make sure the headers are clean
                memset( reporthdr, 0, sizeof(ReportHeader));
                data = &reporthdr->report;
                data->info.transferID = agent->mSock;
                data->info.groupID = 128;
            } else {
                FAIL(1, "Out of Memory!!\n", agent);
            }
        }
        if ( reporthdr != NULL ) {
            data->type |= CONNECTION_REPORT;
            data->connection.peer = agent->peer;
            data->connection.size_peer = agent->size_peer;
            data->connection.local = agent->local;
            data->connection.size_local = agent->size_local;
        } else {
            FAIL(1, "Out of Memory!!\n", agent);
        }
    }
    if ( isConnectionReport( agent ) || isDataReport( agent ) ) {

#ifdef HAVE_THREAD
        /*
         * Update the ReportRoot to include this report.
         */
        if ( reporthdr->report.mThreadMode == kMode_Client &&
             reporthdr->multireport != NULL ) {
            // syncronize watches on my mark......
            BarrierClient( reporthdr );
        } else {
            if ( reporthdr->multireport != NULL && isMultipleReport( agent )) {
                reporthdr->multireport->threads++;
                if ( reporthdr->multireport->report->startTime.tv_sec == 0 ) {
                    gettimeofday( &(reporthdr->multireport->report->startTime), NULL );
                }
                reporthdr->report.startTime = reporthdr->multireport->report->startTime;
            } else {
                // set start time
                gettimeofday( &(reporthdr->report.startTime), NULL );
            }
            reporthdr->report.nextTime = reporthdr->report.startTime;
            TimeAdd( reporthdr->report.nextTime, reporthdr->report.intervalTime );
        }
        Condition_Lock( ReportCond );
        reporthdr->next = ReportRoot;
        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;
}