// -------------------------------------------------------------------------- // KA_stop: Stops the ICMP echo engine and wait for the main keepalive // thread to finish. Retrieve the keepalive status with KA_get_status // after the stop is done. // // Parameters: // p_engine: Opaque pointer to the Keepalive engine. // // Return value: // KA_SUCCESS indicates a successful stop. // KA_ERROR on error. // ka_ret_t KA_stop( void * p_engine ) { PKA_ENGINE_PARMS p_ka_engine = (PKA_ENGINE_PARMS)p_engine; iee_ret_t iee_ret; sint32_t ret; // Check echo engine opaque pointer validity. if( p_ka_engine == NULL || p_ka_engine->p_echo_engine == NULL ) { // Evil is at work someplace.. LOG_MESSAGE( LOG_LEVEL_1, ELError, STR_KA_STOP_FAIL_CAUSE STR_GEN_INVALID_POINTER ); return KA_ERROR; } // Issue the stop to the engine. This will asynchronously cause the KA // thread to exit eventually. iee_ret = IEE_stop( p_ka_engine->p_echo_engine ); if( iee_ret != IEE_SUCCESS ) { // Error stopping the echo engine. LOG_MESSAGE( LOG_LEVEL_1, ELError, STR_KA_STOP_FAIL_CAUSE STR_KA_ERR_STOP_IEE ); return KA_ERROR; } // Wait on the KA thread to finish. ret = pal_thread_join( p_ka_engine->ka_thread_id, NULL ); if( ret != 0 ) { // Error joining the keepalive thread. LOG_MESSAGE( LOG_LEVEL_1, ELError, "%s%d", STR_KA_STOP_FAIL_CAUSE STR_KA_ERR_THREAD_JOIN, ret ); return KA_ERROR; } return KA_SUCCESS; }
/* Fill the distance values for the brokers in a list */ tRedirectStatus tspGetBrokerDistances(tBrokerList *broker_list, int broker_count, tConf *conf) { sint32_t rc = 0; int t = 0; tRedirectStatus status = TSP_REDIRECT_OK; pal_thread_ret_t thread_status = 0; pal_thread_t *threads = NULL; tBrokerTimingThreadArg *thread_arguments = NULL; tBrokerList *broker_list_index = NULL; /* Initialize thread array */ if ((threads = (pal_thread_t *)malloc(broker_count * sizeof(pal_thread_t))) == NULL) { Display(LOG_LEVEL_1, ELError, "tspGetBrokerDistances", GOGO_STR_RDR_CANT_MALLOC_THREAD_ARRAY); return TSP_REDIRECT_CANT_MALLOC_THREAD_ARRAY; } /* Initialize thread argument array */ if ((thread_arguments = (tBrokerTimingThreadArg *)malloc(broker_count * sizeof(tBrokerTimingThreadArg))) == NULL) { free(threads); Display(LOG_LEVEL_1, ELError, "tspGetBrokerDistances", GOGO_STR_RDR_CANT_MALLOC_THREAD_ARGS); return TSP_REDIRECT_CANT_MALLOC_THREAD_ARGS; } /* We start at the beginning of the broker list */ broker_list_index = broker_list; /* Loop through the broker list */ for (t = 0; ((t < broker_count) && (broker_list_index != NULL)); t++) { Display(LOG_LEVEL_3, ELInfo, "tspGetBrokerDistances", GOGO_STR_RDR_CREATING_DISTANCE_THREAD, broker_list_index->address); /* Set the thread arguments */ thread_arguments[t].broker = broker_list_index; thread_arguments[t].conf = conf; /* Start the distance calculation thread for that broker in the list */ rc = pal_thread_create( &threads[t], &tspGetBrokerDistance, (void *)&thread_arguments[t] ); /* If we can't create the thread, return an error */ if( rc != 0 ) { free(threads); free(thread_arguments); Display(LOG_LEVEL_1, ELError, "tspGetBrokerDistances", GOGO_STR_RDR_CANT_CREATE_DISTANCE_THREAD, broker_list_index->address); return TSP_REDIRECT_CANT_CREATE_THREAD; } /* Move to the next broker in the list */ broker_list_index = broker_list_index->next; } /* We start from the begining of the list again to join the threads */ broker_list_index = broker_list; /* Loop through the broker list */ for (t = 0; ((t < broker_count) && (broker_list_index != NULL)); t++) { Display(LOG_LEVEL_3, ELInfo, "tspGetBrokerDistances", GOGO_STR_RDR_WAITING_FOR_THREAD, broker_list_index->address); /* Try to join the thread corresponding to the broker in the list */ rc = pal_thread_join( threads[t], (pal_thread_ret_t*)&thread_status ); /* If we can't join the thread, return an error */ if( rc != 0 ) { free(threads); free(thread_arguments); Display(LOG_LEVEL_1, ELError, "tspGetBrokerDistances", GOGO_STR_RDR_ERR_WAITING_FOR_THREAD, broker_list_index->address); return TSP_REDIRECT_CANT_WAIT_FOR_THREAD; } status = (tRedirectStatus)thread_status; /* The distance was calculated correctly */ if (status == TSP_REDIRECT_OK) { Display(LOG_LEVEL_3, ELInfo, "tspGetBrokerDistances", GOGO_STR_RDR_DISTANCE_CALCULATION_OK, broker_list_index->address, broker_list_index->distance); } /* Echo requests timed out */ else if (status == TSP_REDIRECT_ECHO_REQUEST_TIMEOUT) { Display(LOG_LEVEL_3, ELInfo, "tspGetBrokerDistances", GOGO_STR_RDR_DISTANCE_CALCULATION_TIMEOUT, broker_list_index->address); } /* There was an error somewhere */ else { Display(LOG_LEVEL_1, ELError, "tspGetBrokerDistances", GOGO_STR_RDR_DISTANCE_CALCULATION_ERR, broker_list_index->address); } /* We move to the next broker in the list */ broker_list_index = broker_list_index->next; } free(threads); free(thread_arguments); return TSP_REDIRECT_OK; }