Skip to content

Commit

Permalink
#415 Perform running execution health check inside cse_execution_get_…
Browse files Browse the repository at this point in the history
…status. Keep throwing if an error already has occurred.
  • Loading branch information
eidekrist committed Oct 18, 2019
1 parent 8cd0ebd commit 2fb3445
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 39 deletions.
23 changes: 7 additions & 16 deletions include/cse.h
Original file line number Diff line number Diff line change
Expand Up @@ -290,7 +290,7 @@ int cse_execution_simulate_until(cse_execution* execution, cse_time_point target
* Starts an execution (non blocking).
*
* The execution will run until `cse_execution_stop()` is called. The status of the
* simulation can be polled with `cse_execution_get_simulation_status()`.
* simulation can be polled with `cse_execution_get_status()`.
*
* \param [in] execution
* The execution to be started.
Expand All @@ -300,20 +300,6 @@ int cse_execution_simulate_until(cse_execution* execution, cse_time_point target
*/
int cse_execution_start(cse_execution* execution);


/**
* Polls an execution for its simulation status.
*
* This method can be used to poll the status of the asynchronous execution
* started by calling `cse_execution_start()`. Will return failure if an error
* occurred during the execution.
*
* \returns
* 0 on success and -1 on error.
*/
int cse_execution_get_simulation_status(cse_execution* execution);


/**
* Stops an execution.
*
Expand Down Expand Up @@ -363,7 +349,12 @@ typedef struct
} cse_execution_status;

/**
* Returns execution status.
* Returns execution status.
*
* This method will also poll the status of any asynchronous execution started
* by calling `cse_execution_start()`. Will return failure if a simulation
* error occured during the execution, in which case the `status` parameter
* will still be valid.
*
* \param [in] execution
* The execution to get status from.
Expand Down
29 changes: 15 additions & 14 deletions src/c/cse.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ struct cse_execution_s
std::unique_ptr<cse::execution> cpp_execution;
std::thread t;
boost::fibers::future<bool> simulate_result;
std::exception_ptr simulate_exception_ptr;
std::atomic<cse_execution_state> state;
int error_code;
};
Expand Down Expand Up @@ -507,24 +508,19 @@ int cse_execution_start(cse_execution* execution)
}
}

int cse_execution_get_simulation_status(cse_execution* execution)
void execution_async_health_check(cse_execution* execution)
{
if (execution->state != CSE_EXECUTION_RUNNING) {
return success;
}
const auto status = execution->simulate_result.wait_for(std::chrono::duration<int64_t>());
if (boost::fibers::future_status::ready == status) {
if (auto ep = execution->simulate_result.get_exception_ptr()) {
try {
std::rethrow_exception(ep);
} catch (...) {
handle_current_exception();
execution->state = CSE_EXECUTION_ERROR;
return failure;
if (execution->simulate_result.valid()) {
const auto status = execution->simulate_result.wait_for(std::chrono::duration<int64_t>());
if (boost::fibers::future_status::ready == status) {
if (auto ep = execution->simulate_result.get_exception_ptr()) {
execution->simulate_exception_ptr = ep;
}
}
}
return success;
if (auto ep = execution->simulate_exception_ptr) {
std::rethrow_exception(ep);
}
}

int cse_execution_stop(cse_execution* execution)
Expand Down Expand Up @@ -554,9 +550,14 @@ int cse_execution_get_status(cse_execution* execution, cse_execution_status* sta
status->real_time_factor = execution->cpp_execution->get_measured_real_time_factor();
status->real_time_factor_target = execution->cpp_execution->get_real_time_factor_target();
status->is_real_time_simulation = execution->cpp_execution->is_real_time_simulation() ? 1 : 0;
execution_async_health_check(execution);
return success;
} catch (...) {
handle_current_exception();
execution->error_code = cse_last_error_code();
execution->state = CSE_EXECUTION_ERROR;
status->error_code = execution->error_code;
status->state = execution->state;
return failure;
}
}
Expand Down
27 changes: 18 additions & 9 deletions test/c/simulation_error_handling_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,14 +62,21 @@ int main()
rc = cse_execution_step(execution, 1);
if (rc < 0) { goto Lerror; }

cse_execution_status status;
rc = cse_execution_get_status(execution, &status);
if (rc < 0) {
fprintf(stderr, "Expected call to cse_execution_get_status() 1 to return success.");
goto Lfailure;
}

rc = cse_execution_start(execution);
if (rc < 0) { goto Lerror; }

Sleep(100);

rc = cse_execution_get_simulation_status(execution);
rc = cse_execution_get_status(execution, &status);
if (rc < 0) {
fprintf(stderr, "Expected call to cse_execution_get_simulation_status() to return success.");
fprintf(stderr, "Expected call to cse_execution_get_status() 2 to return success.");
goto Lfailure;
}

Expand All @@ -82,18 +89,20 @@ int main()
// Need to wait a bit due to stepping (and failure) happening in another thread.
Sleep(400);

rc = cse_execution_get_simulation_status(execution);
rc = cse_execution_get_status(execution, &status);
if (rc >= 0) {
fprintf(stderr, "Expected call to cse_execution_get_simulation_status() to return failure.");
fprintf(stderr, "Expected call to cse_execution_get_status() 3 to return failure.");
goto Lfailure;
}

cse_execution_status executionStatus;
rc = cse_execution_get_status(execution, &executionStatus);
if (rc < 0) { goto Lerror; }
rc = cse_execution_get_status(execution, &status);
if (rc >= 0) {
fprintf(stderr, "Expected call to cse_execution_get_status() 4 to return failure.");
goto Lfailure;
}

if (executionStatus.state != CSE_EXECUTION_ERROR) {
fprintf(stderr, "Expected state == %i, got %i\n", CSE_EXECUTION_ERROR, executionStatus.state);
if (status.state != CSE_EXECUTION_ERROR) {
fprintf(stderr, "Expected state == %i, got %i\n", CSE_EXECUTION_ERROR, status.state);
goto Lfailure;
}

Expand Down

0 comments on commit 2fb3445

Please sign in to comment.