00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00031 #ifndef __AUTOSCAN_INOTIFY_H__
00032 #define __AUTOSCAN_INOTIFY_H__
00033
00034 #include "zmmf/zmmf.h"
00035 #include "sync.h"
00036 #include "hash.h"
00037 #include "autoscan.h"
00038 #include "mt_inotify.h"
00039
00040 #define INOTIFY_ROOT -1
00041 #define INOTIFY_UNKNOWN_PARENT_WD -2
00042
00043 typedef enum inotify_watch_type_t
00044 {
00045 InotifyWatchTypeNonexisting,
00046 InotifyWatchTypeAutoscan
00047 };
00048
00049 class AutoscanInotify : public zmm::Object
00050 {
00051 public:
00052 AutoscanInotify();
00053 virtual ~AutoscanInotify();
00054 void init();
00055
00059 void shutdown();
00060
00062 void monitor(zmm::Ref<AutoscanDirectory> dir);
00063
00065 void unmonitor(zmm::Ref<AutoscanDirectory> dir);
00066
00067 private:
00068 static void *staticThreadProc(void *arg);
00069 void threadProc();
00070
00071 pthread_t thread;
00072
00073 zmm::Ref<Inotify> inotify;
00074
00075 zmm::Ref<Cond> cond;
00076 zmm::Ref<Mutex> mutex;
00077
00078 zmm::Ref<zmm::ObjectQueue<AutoscanDirectory> > monitorQueue;
00079 zmm::Ref<zmm::ObjectQueue<AutoscanDirectory> > unmonitorQueue;
00080
00081
00082 int events;
00083
00084 typedef enum watch_type_t
00085 {
00086 WatchAutoscanType,
00087 WatchMoveType
00088 };
00089
00090 class Watch : public zmm::Object
00091 {
00092 public:
00093 Watch(watch_type_t type)
00094 {
00095 this->type = type;
00096 }
00097 watch_type_t getType() { return type; }
00098 private:
00099 watch_type_t type;
00100 };
00101
00102 class WatchAutoscan : public Watch
00103 {
00104 public:
00105 WatchAutoscan(bool startPoint, zmm::Ref<AutoscanDirectory> adir, zmm::String normalizedAutoscanPath) : Watch(WatchAutoscanType)
00106 {
00107 setAutoscanDirectory(adir);
00108 setNormalizedAutoscanPath(normalizedAutoscanPath);
00109 setNonexistingPathArray(nil);
00110 this->startPoint = startPoint;
00111 this->descendants = nil;
00112 }
00113 zmm::Ref<AutoscanDirectory> getAutoscanDirectory() { return adir; }
00114 void setAutoscanDirectory(zmm::Ref<AutoscanDirectory> adir) { this->adir = adir; }
00115 zmm::String getNormalizedAutoscanPath() { return normalizedAutoscanPath; }
00116 void setNormalizedAutoscanPath(zmm::String normalizedAutoscanPath) { this->normalizedAutoscanPath = normalizedAutoscanPath; }
00117 bool isStartPoint() { return startPoint; }
00118 zmm::Ref<zmm::Array<zmm::StringBase> > getNonexistingPathArray() { return nonexistingPathArray; }
00119 void setNonexistingPathArray(zmm::Ref<zmm::Array<zmm::StringBase> > nonexistingPathArray) { this->nonexistingPathArray = nonexistingPathArray; }
00120 void addDescendant(int wd)
00121 {
00122 if (descendants == nil)
00123 descendants = zmm::Ref<zmm::IntArray>(new zmm::IntArray());
00124 descendants->append(wd);
00125 }
00126 zmm::Ref<zmm::IntArray> getDescendants() { return descendants; }
00127 private:
00128 zmm::Ref<AutoscanDirectory> adir;
00129 bool startPoint;
00130 zmm::Ref<zmm::IntArray> descendants;
00131 zmm::String normalizedAutoscanPath;
00132 zmm::Ref<zmm::Array<zmm::StringBase> > nonexistingPathArray;
00133 };
00134
00135 class WatchMove : public Watch
00136 {
00137 public:
00138 WatchMove(int removeWd) : Watch(WatchMoveType)
00139 {
00140 this->removeWd = removeWd;
00141 }
00142 int getRemoveWd() { return removeWd; }
00143 private:
00144 int removeWd;
00145 };
00146
00147 class Wd : public zmm::Object
00148 {
00149 public:
00150 Wd(zmm::String path, int wd, int parentWd)
00151 {
00152 wdWatches = zmm::Ref<zmm::Array<Watch> >(new zmm::Array<Watch>(1));
00153 this->path = path;
00154 this->wd = wd;
00155 this->parentWd = parentWd;
00156 }
00157 zmm::String getPath() { return path; }
00158 int getWd() { return wd; }
00159 int getParentWd() { return parentWd; }
00160 void setParentWd(int parentWd) { this->parentWd = parentWd; }
00161 zmm::Ref<zmm::Array<Watch> > getWdWatches() { return wdWatches; }
00162 private:
00163 zmm::Ref<zmm::Array<Watch> > wdWatches;
00164 zmm::String path;
00165 int parentWd;
00166 int wd;
00167 };
00168
00169 zmm::Ref<DBOHash<int, Wd> > watches;
00170
00171 zmm::String normalizePathNoEx(zmm::String path);
00172
00173 void monitorUnmonitorRecursive(zmm::String startPath, bool unmonitor, zmm::Ref<AutoscanDirectory> adir, zmm::String normalizedAutoscanPath, bool startPoint);
00174 int monitorDirectory(zmm::String path, zmm::Ref<AutoscanDirectory> adir, zmm::String normalizedAutoscanPath, bool startPoint, zmm::Ref<zmm::Array<zmm::StringBase> > pathArray = nil);
00175 void unmonitorDirectory(zmm::String path, zmm::Ref<AutoscanDirectory> adir);
00176
00177 zmm::Ref<WatchAutoscan> getAppropriateAutoscan(zmm::Ref<Wd> wdObj, zmm::Ref<AutoscanDirectory> adir);
00178 zmm::Ref<WatchAutoscan> getAppropriateAutoscan(zmm::Ref<Wd> wdObj, zmm::String path);
00179 zmm::Ref<WatchAutoscan> getStartPoint(zmm::Ref<Wd> wdObj);
00180
00181 bool removeFromWdObj(zmm::Ref<Wd> wdObj, zmm::Ref<Watch> toRemove);
00182 bool removeFromWdObj(zmm::Ref<Wd> wdObj, zmm::Ref<WatchAutoscan> toRemove);
00183 bool removeFromWdObj(zmm::Ref<Wd> wdObj, zmm::Ref<WatchMove> toRemove);
00184
00185 void monitorNonexisting(zmm::String path, zmm::Ref<AutoscanDirectory> adir, zmm::String normalizedAutoscanPath);
00186 void recheckNonexistingMonitor(int curWd, zmm::Ref<zmm::Array<zmm::StringBase> > nonexistingPathArray, zmm::Ref<AutoscanDirectory> adir, zmm::String normalizedAutoscanPath);
00187 void recheckNonexistingMonitors(int wd, zmm::Ref<Wd> wdObj);
00188 void removeNonexistingMonitor(int wd, zmm::Ref<Wd> wdObj, zmm::Ref<zmm::Array<zmm::StringBase> > pathAr);
00189
00190 int watchPathForMoves(zmm::String path, int wd);
00191 int addMoveWatch(zmm::String path, int removeWd, int parentWd);
00192 void checkMoveWatches(int wd, zmm::Ref<Wd> wdObj);
00193 void removeWatchMoves(int wd);
00194
00195 void addDescendant(int startPointWd, int addWd, zmm::Ref<AutoscanDirectory> adir);
00196 void removeDescendants(int wd);
00197
00199 bool shutdownFlag;
00200 };
00201
00202 #endif // __AUTOSCAN_INOTIFY_H__