MOAB: Mesh Oriented datABase  (version 5.2.1)
MsqInterrupt.cpp
Go to the documentation of this file.
00001 /* *****************************************************************
00002     MESQUITE -- The Mesh Quality Improvement Toolkit
00003 
00004     Copyright 2004 Sandia Corporation and Argonne National
00005     Laboratory.  Under the terms of Contract DE-AC04-94AL85000
00006     with Sandia Corporation, the U.S. Government retains certain
00007     rights in this software.
00008 
00009     This library is free software; you can redistribute it and/or
00010     modify it under the terms of the GNU Lesser General Public
00011     License as published by the Free Software Foundation; either
00012     version 2.1 of the License, or (at your option) any later version.
00013 
00014     This library is distributed in the hope that it will be useful,
00015     but WITHOUT ANY WARRANTY; without even the implied warranty of
00016     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00017     Lesser General Public License for more details.
00018 
00019     You should have received a copy of the GNU Lesser General Public License
00020     (lgpl.txt) along with this library; if not, write to the Free Software
00021     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00022 
00023   ***************************************************************** */
00024 
00025 #include "MsqInterrupt.hpp"
00026 #include <signal.h>
00027 
00028 namespace MBMesquite
00029 {
00030 
00031 unsigned MsqInterrupt::instanceCount                    = 0;
00032 bool MsqInterrupt::sawInterrupt                         = false;
00033 MsqInterrupt::InterruptMode MsqInterrupt::interruptMode = MsqInterrupt::AUTO;
00034 
00035 extern "C" {
00036 typedef void ( *msq_sig_handler_t )( int );
00037 }
00038 msq_sig_handler_t oldHandler = SIG_ERR;
00039 
00040 extern "C" void msq_sigint_handler( int )
00041 {
00042     MsqInterrupt::set_interrupt();
00043     if( oldHandler != SIG_DFL && oldHandler != SIG_IGN ) oldHandler( SIGINT );
00044     MsqInterrupt::set_handler();
00045 }
00046 
00047 void MsqInterrupt::set_handler()
00048 {
00049     oldHandler = signal( SIGINT, &msq_sigint_handler );
00050     if( MsqInterrupt::interruptMode == MsqInterrupt::AUTO && ( oldHandler == SIG_DFL || oldHandler == SIG_IGN ) )
00051     {
00052         signal( SIGINT, oldHandler );
00053         oldHandler = SIG_ERR;
00054     }
00055 }
00056 
00057 void MsqInterrupt::disable( MsqError& /*err*/ )
00058 {
00059     interruptMode = IGNORE;
00060     if( instanceCount && SIG_ERR != oldHandler )
00061     {
00062         signal( SIGINT, oldHandler );
00063         oldHandler = SIG_ERR;
00064     }
00065     sawInterrupt = false;
00066 }
00067 
00068 void MsqInterrupt::enable( MsqError& /*err*/ )
00069 {
00070     sawInterrupt  = false;
00071     interruptMode = CATCH;
00072     if( instanceCount && SIG_ERR == oldHandler ) set_handler();
00073 }
00074 
00075 void MsqInterrupt::allow( MsqError& /*err*/ )
00076 {
00077     sawInterrupt  = false;
00078     interruptMode = AUTO;
00079     if( instanceCount && SIG_ERR == oldHandler ) set_handler();
00080 }
00081 
00082 MsqInterrupt::MsqInterrupt()
00083 {
00084     if( !instanceCount )
00085     {
00086         if( IGNORE != interruptMode ) set_handler();
00087         sawInterrupt = false;
00088     }
00089     ++instanceCount;
00090 }
00091 
00092 MsqInterrupt::~MsqInterrupt()
00093 {
00094     if( !--instanceCount && SIG_ERR != oldHandler )
00095     {
00096         signal( SIGINT, oldHandler );
00097         oldHandler = SIG_ERR;
00098     }
00099     sawInterrupt = false;
00100 }
00101 
00102 }  // namespace MBMesquite
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines