00001 /** 00002 \file Robots/LoBot/misc/LoShutdown.H 00003 \brief An object to signal and coordinate an orderly application 00004 shutdown. 00005 00006 This file defines a class that implements a thread that simply waits 00007 for a termination signal (SIGINT, SIGHUP, etc.). It provides an API 00008 for the other Robolocust modules/threads to check if application 00009 shutdown is in progress and take appropriate clean-up action. 00010 */ 00011 00012 // //////////////////////////////////////////////////////////////////// // 00013 // The iLab Neuromorphic Vision C++ Toolkit - Copyright (C) 2000-2005 // 00014 // by the University of Southern California (USC) and the iLab at USC. // 00015 // See http://iLab.usc.edu for information about this project. // 00016 // //////////////////////////////////////////////////////////////////// // 00017 // Major portions of the iLab Neuromorphic Vision Toolkit are protected // 00018 // under the U.S. patent ``Computation of Intrinsic Perceptual Saliency // 00019 // in Visual Environments, and Applications'' by Christof Koch and // 00020 // Laurent Itti, California Institute of Technology, 2001 (patent // 00021 // pending; application number 09/912,225 filed July 23, 2001; see // 00022 // http://pair.uspto.gov/cgi-bin/final/home.pl for current status). // 00023 // //////////////////////////////////////////////////////////////////// // 00024 // This file is part of the iLab Neuromorphic Vision C++ Toolkit. // 00025 // // 00026 // The iLab Neuromorphic Vision C++ Toolkit is free software; you can // 00027 // redistribute it and/or modify it under the terms of the GNU General // 00028 // Public License as published by the Free Software Foundation; either // 00029 // version 2 of the License, or (at your option) any later version. // 00030 // // 00031 // The iLab Neuromorphic Vision C++ Toolkit is distributed in the hope // 00032 // that it will be useful, but WITHOUT ANY WARRANTY; without even the // 00033 // implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // 00034 // PURPOSE. See the GNU General Public License for more details. // 00035 // // 00036 // You should have received a copy of the GNU General Public License // 00037 // along with the iLab Neuromorphic Vision C++ Toolkit; if not, write // 00038 // to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, // 00039 // Boston, MA 02111-1307 USA. // 00040 // //////////////////////////////////////////////////////////////////// // 00041 // 00042 // Primary maintainer for this file: mviswana usc edu 00043 // $HeadURL: svn://isvn.usc.edu/software/invt/trunk/saliency/src/Robots/LoBot/thread/LoShutdown.H $ 00044 // $Id: LoShutdown.H 13521 2010-06-06 14:23:03Z mviswana $ 00045 // 00046 00047 #ifndef LOBOT_SHUTDOWN_DOT_H 00048 #define LOBOT_SHUTDOWN_DOT_H 00049 00050 //------------------------------ HEADERS -------------------------------- 00051 00052 // lobot headers 00053 #include "Robots/LoBot/thread/LoThread.H" 00054 #include "Robots/LoBot/misc/singleton.hh" 00055 00056 // POSIX threads 00057 #ifdef INVT_HAVE_LIBPTHREAD 00058 00059 #include <pthread.h> 00060 00061 #else // fake pthreads API to allow builds to succeed 00062 00063 typedef int pthread_rwlock_t ; 00064 00065 #endif 00066 00067 // Standard C headers 00068 #include <signal.h> 00069 00070 //----------------------------- NAMESPACE ------------------------------- 00071 00072 namespace lobot { 00073 00074 //------------------------- CLASS DEFINITION ---------------------------- 00075 00076 /** 00077 \class lobot::Shutdown 00078 \brief A thread that waits for a shutdown signal and allows other 00079 modules/threads to query whether shutdown is in progress or not. 00080 00081 This class implements a signal handling thread that simply waits for 00082 one of the SIGINT, SIGHUP, etc. signals to be sent to the Robolocust 00083 application. Once such a signal is delivered, it updates its internal 00084 state to reflect that the application is to be shutdown. All other 00085 Robolocust threads are required to monitor this Shutdown object in 00086 their respective main loops and break out of these loops when shutdown 00087 has been signaled. 00088 */ 00089 class Shutdown : public singleton<Shutdown>, private Thread { 00090 // Prevent copy and assignment 00091 Shutdown(const Shutdown&) ; 00092 Shutdown& operator=(const Shutdown&) ; 00093 00094 // Boilerplate code to make the generic singleton design pattern work 00095 friend class singleton<Shutdown> ; 00096 00097 /// The shutdown object listens for the signals specified by this 00098 /// mask. 00099 static sigset_t m_signals_mask ; 00100 00101 /// This flag indicates whether or not the shutdown thread has begun 00102 /// listening for app termination signals. It is used in conjunction 00103 /// with the current thread count to try an enforce the restriction 00104 /// that the start_listening() method be called only once and that too 00105 /// only from the application's main thread. 00106 static bool m_listening ; 00107 00108 /// The shutdown object uses this flag to indicate whether or not it 00109 /// has received a shutdown signal. 00110 bool m_shutdown ; 00111 00112 /// Since the above flag can be accessed by multiple threads, we need 00113 /// to synchronize accesses to it. Since the Shutdown object's signal 00114 /// handling thread is the only one that will ever write to the above 00115 /// variable and since all the other threads in the Robolocust system 00116 /// will only read it, we can use a reader-writer lock rather than a 00117 /// mutex. 00118 pthread_rwlock_t m_shutdown_lock ; 00119 00120 /// A private constructor because this class is a singleton. 00121 Shutdown() ; 00122 00123 /// This method implements the shutdown thread's custom processing, 00124 /// which takes care of the necessary signal handling logic. 00125 void run() ; 00126 00127 public: 00128 /// A convenience method for setting up the signals mask and starting 00129 /// the shutdown signals monitoring thread. 00130 /// 00131 /// NOTE: This method should be called sometime early on in the 00132 /// application's lifetime. Moreover, it *must* be called *only* by 00133 /// the application's main thread. 00134 static void start_listening() ; 00135 00136 /// Let clients know whether a shutdown signal has been received or 00137 /// not. 00138 static bool signaled() ; 00139 00140 /// Allow a client to explicitly post a SIGTERM to the shutdown 00141 /// thread. 00142 static void signal() ; 00143 00144 /// Clean-up. 00145 ~Shutdown() ; 00146 } ; 00147 00148 //----------------------------------------------------------------------- 00149 00150 } // end of namespace encapsulating this file's definitions 00151 00152 #endif 00153 00154 /* So things look consistent in everyone's emacs... */ 00155 /* Local Variables: */ 00156 /* indent-tabs-mode: nil */ 00157 /* End: */