diff --git a/src/Apps/AmplSolver/AmplTNLP.cpp b/src/Apps/AmplSolver/AmplTNLP.cpp index 90621f872..bc686eb24 100644 --- a/src/Apps/AmplSolver/AmplTNLP.cpp +++ b/src/Apps/AmplSolver/AmplTNLP.cpp @@ -170,7 +170,7 @@ void AmplTNLP::gutsOfConstructor( } } - if( checkinterrupt_ && !RegisterInterruptHandler(NULL, &interrupted_) ) + if( checkinterrupt_ && !RegisterInterruptHandler(NULL, &interrupted_, 5) ) { jnlst_->Printf(J_STRONGWARNING, J_MAIN, "Could not register handler for interrupt signals.\n"); } diff --git a/src/Common/IpUtils.cpp b/src/Common/IpUtils.cpp index 6f50a639e..8ba03c7b7 100644 --- a/src/Common/IpUtils.cpp +++ b/src/Common/IpUtils.cpp @@ -194,6 +194,7 @@ Number WallclockTime() } static bool registered_handler = false; +static unsigned int abortcountdown_ = std::numeric_limits::max(); static void (*handle_interrupt_)(void) = NULL; static bool* interrupt_flag_ = NULL; @@ -210,19 +211,18 @@ static void sighandler( { (*handle_interrupt_)(); } + + if( --abortcountdown_ == 0 ) + { + fputs("Ipopt sighandler: Too many interrupt signals. Forcing termination.\n", stderr); + exit(1); + } } -/** register handler for interrupt signals - * - * On POSIX systems, catches SIGHUP and SIGINT signals. - * On Windows, catches SIGTERM, SIGABRT, SIGBREAK, and SIGINT signals. - * - * @return whether registering the handler was successful - * @since 3.14.17 - */ bool RegisterInterruptHandler( - void (*handle_interrupt)(void), /**< function to call when interrupted by signal, if not NULL */ - bool* interrupt_flag /**< variable to set to true when interrupted by signal, if not NULL */ + void (*handle_interrupt)(void), + bool* interrupt_flag, + unsigned int abortlimit ) { if( registered_handler ) @@ -230,6 +230,7 @@ bool RegisterInterruptHandler( return false; } registered_handler = true; + abortcountdown_ = abortlimit; handle_interrupt_ = handle_interrupt; interrupt_flag_ = interrupt_flag; @@ -260,11 +261,6 @@ bool RegisterInterruptHandler( return true; } -/** unregister previously registered handler for interrupt signals - * - * @return whether registering the handler was successful - * @since 3.14.17 - */ bool UnregisterInterruptHandler(void) { if( !registered_handler ) diff --git a/src/Common/IpUtils.hpp b/src/Common/IpUtils.hpp index c6684cb7f..909f93d6f 100644 --- a/src/Common/IpUtils.hpp +++ b/src/Common/IpUtils.hpp @@ -109,8 +109,9 @@ IPOPTLIB_EXPORT Number WallclockTime(); * @since 3.14.17 */ IPOPTLIB_EXPORT bool RegisterInterruptHandler( - void (*handle_interrupt)(void), /**< function to call when interrupted by signal, if not NULL */ - bool* interrupt_flag /**< variable to set to true when interrupted by signal, if not NULL */ + void (*handle_interrupt)(void), /**< function to call when interrupted by signal, if not NULL */ + bool* interrupt_flag, /**< variable to set to true when interrupted by signal, if not NULL */ + unsigned int abortlimit = std::numeric_limits::max() /**< if interrupt signal has been send this many times, then exit(1) */ ); /** unregister previously registered handler for interrupt signals