1 // Copyright 2010-2021 Google LLC 2 // Licensed under the Apache License, Version 2.0 (the "License"); 3 // you may not use this file except in compliance with the License. 4 // You may obtain a copy of the License at 5 // 6 // http://www.apache.org/licenses/LICENSE-2.0 7 // 8 // Unless required by applicable law or agreed to in writing, software 9 // distributed under the License is distributed on an "AS IS" BASIS, 10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 11 // See the License for the specific language governing permissions and 12 // limitations under the License. 13 14 #include "ortools/util/sigint.h" 15 16 #include <csignal> 17 18 #include "ortools/base/logging.h" 19 20 namespace operations_research { 21 Register(const std::function<void ()> & f)22void SigintHandler::Register(const std::function<void()>& f) { 23 handler_ = [this, f]() -> void { 24 ++num_sigint_calls_; 25 if (num_sigint_calls_ >= 3) { 26 LOG(INFO) << "^C pressed " << num_sigint_calls_ 27 << " times. Forcing termination."; 28 exit(EXIT_FAILURE); 29 } 30 LOG(INFO) << "^C pressed " << num_sigint_calls_ << " times. " 31 << "Interrupting the solver. Press 3 times to force termination."; 32 if (num_sigint_calls_ == 1) f(); 33 }; 34 signal(SIGINT, &ControlCHandler); 35 } 36 37 // This method will be called by the system after the SIGINT signal. 38 // The parameter is the signal received. ControlCHandler(int sig)39void SigintHandler::ControlCHandler(int sig) { handler_(); } 40 41 // Unregister the SIGINT handler. ~SigintHandler()42SigintHandler::~SigintHandler() { signal(SIGINT, SIG_DFL); } 43 44 thread_local std::function<void()> SigintHandler::handler_; 45 46 } // namespace operations_research 47