Changeset 944
- Timestamp:
- Aug 5, 2011, 5:02:29 PM (14 years ago)
- Location:
- trunk/src/corelib/io
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/corelib/io/qfilesystemwatcher_os2.cpp
r943 r944 94 94 QT_BEGIN_NAMESPACE 95 95 96 QOS2FileSystemWatcherEngine::QOS2FileSystemWatcherEngine() 97 : notifyPipe(NULLHANDLE), eventSem(NULLHANDLE), isRunning(false) 96 class QOS2FileSysWatcherThread : public QThread 97 { 98 public: 99 100 static void addRef(); 101 static void release(); 102 103 static QStringList addPaths(QOS2FileSystemWatcherEngine *engine, 104 const QStringList &paths, 105 QStringList *files, 106 QStringList *directories); 107 108 static QStringList removePaths(QOS2FileSystemWatcherEngine *engine, 109 const QStringList &paths, 110 QStringList *files, 111 QStringList *directories); 112 113 static void removePaths(QOS2FileSystemWatcherEngine *engine); 114 115 static bool isOk() { return instance->notifyPipe != NULLHANDLE; } 116 117 private: 118 119 QOS2FileSysWatcherThread(); 120 ~QOS2FileSysWatcherThread(); 121 122 void run(); 123 124 int refcnt; 125 126 bool finish; 127 HFILE notifyPipe; 128 HEV eventSem; 129 130 enum Type { None = 0, Dir, File }; 131 struct PathInfo 132 { 133 PathInfo(QString &p, Type t, QOS2FileSystemWatcherEngine *e = 0) 134 : path(p), type(t) { if (e) engines.append(e); } 135 QString path; 136 Type type; 137 QList<QOS2FileSystemWatcherEngine *> engines; 138 }; 139 QHash<QString, QList<PathInfo> > watchedPaths; 140 141 static QOS2FileSysWatcherThread *instance; 142 static QMutex mutex; 143 }; 144 145 // static 146 QOS2FileSysWatcherThread *QOS2FileSysWatcherThread::instance = 0; 147 QMutex QOS2FileSysWatcherThread::mutex; 148 149 // static 150 void QOS2FileSysWatcherThread::addRef() 151 { 152 QMutexLocker locker(&mutex); 153 154 if (instance == 0) { 155 instance = new QOS2FileSysWatcherThread(); 156 } 157 158 ++instance->refcnt; 159 } 160 161 // static 162 void QOS2FileSysWatcherThread::release() 163 { 164 QMutexLocker locker(&mutex); 165 166 Q_ASSERT(instance); 167 168 if (--instance->refcnt == 0) { 169 // make sure we don't globally exist anymore before leaving the lock 170 QOS2FileSysWatcherThread *instance = QOS2FileSysWatcherThread::instance; 171 QOS2FileSysWatcherThread::instance = 0; 172 if (instance->isRunning()) { 173 // stop the thread 174 instance->finish = true; 175 locker.unlock(); 176 DosPostEventSem(instance->eventSem); 177 instance->wait(); 178 } 179 delete instance; 180 } 181 } 182 183 QOS2FileSysWatcherThread::QOS2FileSysWatcherThread() 184 : refcnt(0), finish(false), notifyPipe(NULLHANDLE), eventSem(NULLHANDLE) 98 185 { 99 186 ULONG dummy, retries = 3; … … 138 225 } 139 226 140 QOS2FileSystemWatcherEngine::~QOS2FileSystemWatcherEngine() 141 { 227 QOS2FileSysWatcherThread::~QOS2FileSysWatcherThread() 228 { 229 Q_ASSERT(!refcnt); 230 Q_ASSERT(!watchedPaths.size()); 231 142 232 if (notifyPipe != NULLHANDLE) { 143 233 DosCloseEventSem(eventSem); … … 146 236 } 147 237 148 QStringList QOS2FileSystemWatcherEngine::addPaths(const QStringList &paths, 149 QStringList *files, 150 QStringList *directories) 238 QStringList QOS2FileSysWatcherThread::addPaths(QOS2FileSystemWatcherEngine *engine, 239 const QStringList &paths, 240 QStringList *files, 241 QStringList *directories) 151 242 { 152 243 QMutexLocker locker(&mutex); … … 159 250 if (!fi.exists()) 160 251 continue; 252 161 253 QString normalPath = fi.absoluteFilePath(); 162 254 normalPath = QDir::toNativeSeparators(QDir::cleanPath(path)).toUpper(); … … 171 263 files->append(path); 172 264 } 173 QList<PathInfo> &variants = watchedPaths[normalPath]; 265 266 QList<PathInfo> &variants = instance->watchedPaths[normalPath]; 174 267 bool alreadyAdded = false; 175 foreach (const PathInfo &pi, variants) { 176 if (pi.path == path) { 177 alreadyAdded = true; 178 break; 268 for (QList<PathInfo>::iterator pathIt = variants.begin(); 269 pathIt != variants.end(); ++pathIt) { 270 if (pathIt->path == path) { 271 if (pathIt->engines.contains(engine)) { 272 alreadyAdded = true; 273 break; 274 } 275 pathIt->engines.append(engine); 179 276 } 180 277 } … … 182 279 continue; 183 280 184 variants << PathInfo(path, type );281 variants << PathInfo(path, type); 185 282 it.remove(); 186 283 } 187 284 188 if (!i sRunning) {285 if (!i) { 189 286 // (re)start the watcher thread 190 i sRunning = true;191 start(IdlePriority);287 ie; 288 start(IdlePriority); 192 289 } 193 290 … … 195 292 } 196 293 197 QStringList QOS2FileSystemWatcherEngine::removePaths(const QStringList &paths, 198 QStringList *files, 199 QStringList *directories) 294 QStringList QOS2FileSysWatcherThread::removePaths(QOS2FileSystemWatcherEngine *engine, 295 const QStringList &paths, 296 QStringList *files, 297 QStringList *directories) 200 298 { 201 299 QMutexLocker locker(&mutex); … … 207 305 QString normalPath = QDir::current().absoluteFilePath(path); 208 306 normalPath = QDir::toNativeSeparators(QDir::cleanPath(path)).toUpper(); 209 if (watchedPaths.contains(normalPath)) { 210 QList<PathInfo> &variants = watchedPaths[normalPath]; 307 308 if (instance->watchedPaths.contains(normalPath)) { 309 QList<PathInfo> &variants = instance->watchedPaths[normalPath]; 310 211 311 for (QList<PathInfo>::iterator pathIt = variants.begin(); 212 312 pathIt != variants.end(); ++pathIt) { 213 if (pathIt->path == path ) {313 if (pathIt->path == path) { 214 314 files->removeAll(path); 215 315 directories->removeAll(path); 216 variants.erase(pathIt); 316 pathIt->engines.removeAll(engine); 317 if (pathIt->engines.isEmpty()) 318 variants.erase(pathIt); 217 319 it.remove(); 218 320 break; 219 321 } 220 322 } 323 221 324 if (variants.isEmpty()) 222 watchedPaths.remove(normalPath);223 } 224 } 225 226 if ( watchedPaths.isEmpty()) {325 watchedPaths.remove(normalPath); 326 } 327 } 328 329 if (watchedPaths.isEmpty()) { 227 330 // stop the thread 228 i sRunning = false;229 DosPostEventSem( eventSem);331 ie; 332 DosPostEventSem(eventSem); 230 333 } 231 334 … … 233 336 } 234 337 235 void QOS2FileSystemWatcherEngine::run() 338 void QOS2FileSysWatcherThread::removePaths(QOS2FileSystemWatcherEngine *engine) 339 { 340 QMutexLocker locker(&mutex); 341 342 foreach (const QString &normalPath, instance->watchedPaths.keys()) { 343 QList<PathInfo> &variants = instance->watchedPaths[normalPath]; 344 for (QList<PathInfo>::iterator pathIt = variants.begin(); 345 pathIt != variants.end(); ++pathIt) { 346 if (pathIt->engines.contains(engine)) { 347 pathIt->engines.removeAll(engine); 348 if (pathIt->engines.isEmpty()) 349 variants.erase(pathIt); 350 break; 351 } 352 } 353 354 if (variants.isEmpty()) 355 instance->watchedPaths.remove(normalPath); 356 } 357 358 if (instance->watchedPaths.isEmpty()) { 359 // stop the thread 360 instance->finish = true; 361 DosPostEventSem(instance->eventSem); 362 } 363 } 364 365 void QOS2FileSysWatcherThread::run() 236 366 { 237 367 QByteArray buffer(sizeof(CNINFO) + _MAX_PATH + 2, 0); … … 247 377 locker.relock(); 248 378 249 if ( !isRunning)379 if () 250 380 break; 251 381 … … 299 429 type = pi.type; 300 430 if (type == pi.type) { 301 if (type == File) 302 emit fileChanged(pi.path, deleted); 303 else 304 emit directoryChanged(pi.path, deleted); 431 foreach(QOS2FileSystemWatcherEngine *e, pi.engines) { 432 if (type == File) 433 e->doFileChanged(pi.path, deleted); 434 else 435 e->doDirectoryChanged(pi.path, deleted); 436 } 305 437 } 306 438 } … … 316 448 foreach(const PathInfo &pi, watchedPaths[normalPath]) { 317 449 if (pi.type == Dir) 318 emit directoryChanged(pi.path, false); 450 foreach(QOS2FileSystemWatcherEngine *e, pi.engines) 451 e->doDirectoryChanged(pi.path, false); 319 452 } 320 453 } … … 334 467 } 335 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 336 493 void QOS2FileSystemWatcherEngine::stop() 337 494 { 338 Q MutexLocker locker(&mutex);339 if (isRunning) { 340 isRunning = false; 341 DosPostEventSem(eventSem); 342 // note: the caller of stop() will wait() if necessary 343 }495 Q); 496 } 497 498 bool QOS2FileSystemWatcherEngine::isOk() const 499 { 500 344 501 } 345 502 -
trunk/src/corelib/io/qfilesystemwatcher_os2_p.h
r805 r944 68 68 class QOS2FileSystemWatcherEngine : public QFileSystemWatcherEngine 69 69 { 70 Q_OBJECT71 70 public: 72 71 QOS2FileSystemWatcherEngine(); … … 78 77 QStringList *directories); 79 78 80 void run();81 79 void stop(); 80 82 81 83 bool isOk() const { return notifyPipe != NULLHANDLE; }; 84 85 private: 86 mutable QMutex mutex; 87 HFILE notifyPipe; 88 HEV eventSem; 89 bool isRunning; 90 91 enum Type { None = 0, Dir, File }; 92 struct PathInfo 93 { 94 PathInfo(const QString &p, Type t) : path(p), type(t) {} 95 QString path; 96 Type type; 97 }; 98 QHash<QString, QList<PathInfo> > watchedPaths; 82 void doFileChanged(const QString &path, bool removed) { 83 emit fileChanged(path, removed); 84 } 85 void doDirectoryChanged(const QString &path, bool removed) { 86 emit directoryChanged(path, removed); 87 } 99 88 }; 100 89
Note:
See TracChangeset
for help on using the changeset viewer.