Ignore:
Timestamp:
Aug 5, 2011, 11:26:12 PM (14 years ago)
Author:
Dmitry A. Kuminov
Message:

OS/2: Make native QFileSystemWatcher recognize file changes.

The original notification mechanism does not actually implement
the file date/time/size change notification. To solve this,
we add another thread that only check for file attribute changes
at specified polling intervals (using a relatively fast native stat call)
and nothing more.

The file change notification is needed e.g. for Qt Creator which
uses it to detect external file notifications in the editor.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/corelib/io/qfilesystemwatcher_os2.cpp

    r944 r945  
    9494QT_BEGIN_NAMESPACE
    9595
     96
     97
     98
     99
     100
     101
     102
     103
     104
     105
     106
     107
     108
     109
     110
     111
     112
     113
     114
     115
     116
     117
     118
     119
     120
     121
     122
     123
     124
     125
     126
     127
    96128class QOS2FileSysWatcherThread : public QThread
    97129{
     
    113145    static void removePaths(QOS2FileSystemWatcherEngine *engine);
    114146
     147
     148
    115149    static bool isOk() { return instance->notifyPipe != NULLHANDLE; }
    116150
     
    121155
    122156    void run();
     157
     158
    123159
    124160    int refcnt;
     
    127163    HFILE notifyPipe;
    128164    HEV eventSem;
     165
     166
    129167
    130168    enum Type { None = 0, Dir, File };
     
    143181};
    144182
     183
     184
     185
     186
     187
     188
     189
     190
     191
     192
     193
     194
     195
     196
     197
     198
     199
     200
     201
     202
     203
     204
     205
     206
     207
     208
     209
     210
     211
     212
     213
     214
     215
     216
     217
     218
     219
     220
     221
     222
     223
     224
     225
     226
     227
     228
     229
     230
     231
     232
     233
     234
     235
     236
     237
     238
     239
     240
     241
     242
     243
     244
     245
     246
     247
     248
     249
     250
     251
     252
     253
     254
     255
     256
     257
     258
     259
     260
     261
     262
     263
     264
     265
     266
     267
     268
     269
     270
     271
     272
     273
     274
     275
     276
     277
     278
     279
     280
     281
     282
     283
     284
     285
     286
     287
     288
     289
     290
     291
     292
     293
     294
     295
     296
     297
     298
    145299// static
    146300QOS2FileSysWatcherThread *QOS2FileSysWatcherThread::instance = 0;
     
    170324        QOS2FileSysWatcherThread *instance = QOS2FileSysWatcherThread::instance;
    171325        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         }
     326        instance->poller.stop();
     327        instance->stop(locker);
    179328        delete instance;
    180329    }
     
    228377{
    229378    Q_ASSERT(!refcnt);
    230     Q_ASSERT(!watchedPaths.size());
     379    Q_ASSERT(());
    231380
    232381    if (notifyPipe != NULLHANDLE) {
     
    236385}
    237386
     387
    238388QStringList QOS2FileSysWatcherThread::addPaths(QOS2FileSystemWatcherEngine *engine,
    239389                                               const QStringList &paths,
     
    243393    QMutexLocker locker(&mutex);
    244394
    245     QStringList p = paths;
     395    QStringList p = paths;
    246396    QMutableListIterator<QString> it(p);
    247397    while (it.hasNext()) {
     
    264414        }
    265415
     416
     417
     418
    266419        QList<PathInfo> &variants = instance->watchedPaths[normalPath];
    267         bool alreadyAdded = false;
     420        bool alreadyAdded = false;
    268421        for (QList<PathInfo>::iterator pathIt = variants.begin();
    269422             pathIt != variants.end(); ++pathIt) {
    270423            if (pathIt->path == path) {
    271                 if (pathIt->engines.contains(engine)) {
     424                found = true;
     425                if (pathIt->engines.contains(engine))
    272426                    alreadyAdded = true;
    273                     break;
    274                 }
    275                 pathIt->engines.append(engine);
     427               
     428               
     429                ;
    276430            }
    277431        }
     
    279433            continue;
    280434
    281         variants << PathInfo(path, type, engine);
     435        if (!found)
     436            variants << PathInfo(path, type, engine);
    282437        it.remove();
    283438    }
     
    289444    }
    290445
     446
     447
     448
     449
    291450    return p;
    292451}
    293452
     453
    294454QStringList QOS2FileSysWatcherThread::removePaths(QOS2FileSystemWatcherEngine *engine,
    295455                                                  const QStringList &paths,
     
    299459    QMutexLocker locker(&mutex);
    300460
    301     QStringList p = paths;
     461    QStringList p = paths;
    302462    QMutableListIterator<QString> it(p);
    303463    while (it.hasNext()) {
     
    322482            }
    323483
    324             if (variants.isEmpty())
     484            if (variants.isEmpty())
    325485                instance->watchedPaths.remove(normalPath);
    326         }
    327     }
    328 
    329     if (instance->watchedPaths.isEmpty()) {
    330         // stop the thread
    331         instance->finish = true;
    332         DosPostEventSem(instance->eventSem);
    333     }
     486                pollerPaths << normalPath;
     487            }
     488        }
     489    }
     490
     491    // remove unwatched normal paths from the poller
     492    if (!pollerPaths.isEmpty())
     493        instance->poller.removePaths(pollerPaths);
     494
     495    if (instance->watchedPaths.isEmpty())
     496        instance->stop(locker);
    334497
    335498    return p;
    336499}
    337500
     501
    338502void QOS2FileSysWatcherThread::removePaths(QOS2FileSystemWatcherEngine *engine)
    339503{
    340504    QMutexLocker locker(&mutex);
    341505
     506
    342507    foreach (const QString &normalPath, instance->watchedPaths.keys()) {
    343508        QList<PathInfo> &variants = instance->watchedPaths[normalPath];
     
    352517        }
    353518
    354         if (variants.isEmpty())
     519        if (variants.isEmpty())
    355520            instance->watchedPaths.remove(normalPath);
    356     }
    357 
    358     if (instance->watchedPaths.isEmpty()) {
    359         // stop the thread
    360         instance->finish = true;
    361         DosPostEventSem(instance->eventSem);
     521            pollerPaths << normalPath;
     522        }
     523    }
     524
     525    // remove unwatched normal paths from the poller
     526    if (!pollerPaths.isEmpty())
     527        instance->poller.removePaths(pollerPaths);
     528
     529    if (instance->watchedPaths.isEmpty() && instance->isRunning())
     530        instance->stop(locker);
     531}
     532
     533// static
     534void QOS2FileSysWatcherThread::reportChanges(const QStringList &paths)
     535{
     536    QMutexLocker locker(&mutex);
     537
     538    foreach (const QString &path, paths) {
     539        // signal the change
     540        if (instance->watchedPaths.contains(path)) {
     541            QList<PathInfo> &variants = instance->watchedPaths[path];
     542            foreach(const PathInfo &pi, variants) {
     543                foreach(QOS2FileSystemWatcherEngine *e, pi.engines) {
     544                    if (pi.type == File)
     545                        e->doFileChanged(pi.path, false);
     546                    else
     547                        e->doDirectoryChanged(pi.path, false);
     548                }
     549            }
     550        }
    362551    }
    363552}
     
    421610                        bool deleted = info->bAction != RCNF_CHANGED;
    422611                        if (deleted) {
     612
    423613                            deletedVariants = variants;
    424614                            variants = deletedVariants;
     615
    425616                            watchedPaths.remove(normalPath);
     617
    426618                        }
    427619                        foreach(const PathInfo &pi, variants) {
     
    467659}
    468660
     661
     662
     663
     664
     665
     666
     667
     668
     669
     670
     671
     672
     673
     674
     675
    469676QOS2FileSystemWatcherEngine::QOS2FileSystemWatcherEngine()
    470677{
Note: See TracChangeset for help on using the changeset viewer.