Skip to content

Commit

Permalink
[issue1138] Cleanly shut down the planner when it terminates.
Browse files Browse the repository at this point in the history
* Raise exception in exit_with() to ensure that destructors are called upon program exit.
* Add and use non-reentrant report_exit_code() function.
  • Loading branch information
jendrikseipp authored May 29, 2024
1 parent 61646d7 commit ea0f93a
Show file tree
Hide file tree
Showing 4 changed files with 70 additions and 45 deletions.
72 changes: 39 additions & 33 deletions src/search/planner.cc
Original file line number Diff line number Diff line change
Expand Up @@ -13,38 +13,44 @@ using namespace std;
using utils::ExitCode;

int main(int argc, const char **argv) {
utils::register_event_handlers();

if (argc < 2) {
utils::g_log << usage(argv[0]) << endl;
utils::exit_with(ExitCode::SEARCH_INPUT_ERROR);
}

bool unit_cost = false;
if (static_cast<string>(argv[1]) != "--help") {
utils::g_log << "reading input..." << endl;
tasks::read_root_task(cin);
utils::g_log << "done reading input!" << endl;
TaskProxy task_proxy(*tasks::g_root_task);
unit_cost = task_properties::is_unit_cost(task_proxy);
try {
utils::register_event_handlers();

if (argc < 2) {
utils::g_log << usage(argv[0]) << endl;
utils::exit_with(ExitCode::SEARCH_INPUT_ERROR);
}

bool unit_cost = false;
if (static_cast<string>(argv[1]) != "--help") {
utils::g_log << "reading input..." << endl;
tasks::read_root_task(cin);
utils::g_log << "done reading input!" << endl;
TaskProxy task_proxy(*tasks::g_root_task);
unit_cost = task_properties::is_unit_cost(task_proxy);
}

shared_ptr<SearchAlgorithm> search_algorithm =
parse_cmd_line(argc, argv, unit_cost);


utils::Timer search_timer;
search_algorithm->search();
search_timer.stop();
utils::g_timer.stop();

search_algorithm->save_plan_if_necessary();
search_algorithm->print_statistics();
utils::g_log << "Search time: " << search_timer << endl;
utils::g_log << "Total time: " << utils::g_timer << endl;

ExitCode exitcode = search_algorithm->found_solution()
? ExitCode::SUCCESS
: ExitCode::SEARCH_UNSOLVED_INCOMPLETE;
exit_with(exitcode);
} catch (const utils::ExitException &e) {
/* To ensure that all destructors are called before the program exits,
we raise an exception in utils::exit_with() and let main() return. */
return static_cast<int>(e.get_exitcode());
}

shared_ptr<SearchAlgorithm> search_algorithm =
parse_cmd_line(argc, argv, unit_cost);


utils::Timer search_timer;
search_algorithm->search();
search_timer.stop();
utils::g_timer.stop();

search_algorithm->save_plan_if_necessary();
search_algorithm->print_statistics();
utils::g_log << "Search time: " << search_timer << endl;
utils::g_log << "Total time: " << utils::g_timer << endl;

ExitCode exitcode = search_algorithm->found_solution()
? ExitCode::SUCCESS
: ExitCode::SEARCH_UNSOLVED_INCOMPLETE;
exit_with(exitcode);
}
17 changes: 15 additions & 2 deletions src/search/utils/system.cc
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,22 @@ bool is_exit_code_error_reentrant(ExitCode exitcode) {
}
}

void report_exit_code(ExitCode exitcode) {
const char *message = get_exit_code_message_reentrant(exitcode);
bool is_error = is_exit_code_error_reentrant(exitcode);
if (message) {
ostream &stream = is_error ? cerr : cout;
stream << message << endl;
} else {
cerr << "Exitcode: " << static_cast<int>(exitcode) << endl
<< "Unknown exitcode." << endl;
abort();
}
}

void exit_with(ExitCode exitcode) {
report_exit_code_reentrant(exitcode);
exit(static_cast<int>(exitcode));
report_exit_code(exitcode);
throw ExitException(exitcode);
}

void exit_with_reentrant(ExitCode exitcode) {
Expand Down
13 changes: 13 additions & 0 deletions src/search/utils/system.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,13 +53,26 @@ enum class ExitCode {
SEARCH_UNSUPPORTED = 34
};

class ExitException : public std::exception {
ExitCode exitcode;
public:
explicit ExitException(ExitCode exitcode)
: exitcode(exitcode) {
}

ExitCode get_exitcode() const {
return exitcode;
}
};

NO_RETURN extern void exit_with(ExitCode returncode);
NO_RETURN extern void exit_with_reentrant(ExitCode returncode);

int get_peak_memory_in_kb();
const char *get_exit_code_message_reentrant(ExitCode exitcode);
bool is_exit_code_error_reentrant(ExitCode exitcode);
void register_event_handlers();
void report_exit_code(ExitCode exitcode);
void report_exit_code_reentrant(ExitCode exitcode);
int get_process_id();
}
Expand Down
13 changes: 3 additions & 10 deletions src/search/utils/system_windows.cc
Original file line number Diff line number Diff line change
Expand Up @@ -58,16 +58,9 @@ void register_event_handlers() {
}

void report_exit_code_reentrant(ExitCode exitcode) {
const char *message = get_exit_code_message_reentrant(exitcode);
bool is_error = is_exit_code_error_reentrant(exitcode);
if (message) {
ostream &stream = is_error ? cerr : cout;
stream << message << endl;
} else {
cerr << "Exitcode: " << static_cast<int>(exitcode) << endl
<< "Unknown exitcode." << endl;
abort();
}
/* We call a function that uses ostreams even though this is unsafe in
reentrant code, because we don't know how to do it otherwise on Windows. */
report_exit_code(exitcode);
}

int get_process_id() {
Expand Down

0 comments on commit ea0f93a

Please sign in to comment.