00001 /* 00002 * Phusion Passenger - http://www.modrails.com/ 00003 * Copyright (C) 2009 Phusion 00004 * 00005 * Phusion Passenger is a trademark of Hongli Lai & Ninh Bui. 00006 * 00007 * This program is free software; you can redistribute it and/or modify 00008 * it under the terms of the GNU General Public License as published by 00009 * the Free Software Foundation; version 2 of the License. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License along 00017 * with this program; if not, write to the Free Software Foundation, Inc., 00018 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 00019 */ 00020 #ifndef _PASSENGER_FILE_CHECKER_H_ 00021 #define _PASSENGER_FILE_CHECKER_H_ 00022 00023 #include <string> 00024 00025 #include <oxt/system_calls.hpp> 00026 00027 #include <sys/stat.h> 00028 #include <errno.h> 00029 00030 #include "CachedFileStat.h" 00031 #include "SystemTime.h" 00032 00033 namespace Passenger { 00034 00035 using namespace std; 00036 using namespace oxt; 00037 00038 /** 00039 * Utility class for checking for file changes. Example: 00040 * 00041 * @code 00042 * FileChecker checker("foo.txt"); 00043 * checker.changed(); // false 00044 * writeToFile("foo.txt"); 00045 * checker.changed(); // true 00046 * checker.changed(); // false 00047 * @endcode 00048 * 00049 * FileChecker uses stat() to retrieve file information. FileChecker also 00050 * supports throttling in order to limit the number of stat() calls. This 00051 * can improve performance on systems where disk I/O is a problem. 00052 */ 00053 class FileChecker { 00054 private: 00055 CachedFileStat cstat; 00056 time_t lastMtime; 00057 time_t lastCtime; 00058 00059 public: 00060 /** 00061 * Create a FileChecker object. 00062 * 00063 * @param filename The filename to check for. 00064 */ 00065 FileChecker(const string &filename) 00066 : cstat(filename) 00067 { 00068 lastMtime = 0; 00069 lastCtime = 0; 00070 changed(); 00071 } 00072 00073 /** 00074 * Checks whether the file's timestamp has changed or has been created 00075 * or removed since the last call to changed(). 00076 * 00077 * @param throttleRate When set to a non-zero value, throttling will be 00078 * enabled. stat() will be called at most once per 00079 * throttleRate seconds. 00080 * @throws SystemException Something went wrong while retrieving the 00081 * system time. stat() errors will <em>not</em> result in SystemException 00082 * being thrown. 00083 * @throws boost::thread_interrupted 00084 */ 00085 bool changed(unsigned int throttleRate = 0) { 00086 int ret; 00087 time_t ctime, mtime; 00088 bool result; 00089 00090 ret = cstat.refresh(throttleRate); 00091 if (ret == -1) { 00092 ctime = 0; 00093 mtime = 0; 00094 } else { 00095 ctime = cstat.info.st_ctime; 00096 mtime = cstat.info.st_mtime; 00097 } 00098 result = lastMtime != mtime || lastCtime != ctime; 00099 lastMtime = mtime; 00100 lastCtime = ctime; 00101 return result; 00102 } 00103 }; 00104 00105 } // namespace Passenger 00106 00107 #endif /* _PASSENGER_FILE_CHECKER_H_ */