- Main Page
- Modules
- Classes
- Files

# FileChecker.h

    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_ */