file_path_watcher_fsevents.h 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. // Copyright 2014 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #ifndef BASE_FILES_FILE_PATH_WATCHER_FSEVENTS_H_
  5. #define BASE_FILES_FILE_PATH_WATCHER_FSEVENTS_H_
  6. #include <CoreServices/CoreServices.h>
  7. #include <stddef.h>
  8. #include <vector>
  9. #include "base/files/file_path.h"
  10. #include "base/files/file_path_watcher.h"
  11. #include "base/mac/scoped_dispatch_object.h"
  12. #include "base/macros.h"
  13. #include "base/memory/weak_ptr.h"
  14. namespace base {
  15. // Mac-specific file watcher implementation based on FSEvents.
  16. // There are trade-offs between the FSEvents implementation and a kqueue
  17. // implementation. The biggest issues are that FSEvents on 10.6 sometimes drops
  18. // events and kqueue does not trigger for modifications to a file in a watched
  19. // directory. See file_path_watcher_mac.cc for the code that decides when to
  20. // use which one.
  21. class FilePathWatcherFSEvents : public FilePathWatcher::PlatformDelegate {
  22. public:
  23. FilePathWatcherFSEvents();
  24. ~FilePathWatcherFSEvents() override;
  25. // FilePathWatcher::PlatformDelegate overrides.
  26. bool Watch(const FilePath& path,
  27. bool recursive,
  28. const FilePathWatcher::Callback& callback) override;
  29. void Cancel() override;
  30. private:
  31. static void FSEventsCallback(ConstFSEventStreamRef stream,
  32. void* event_watcher,
  33. size_t num_events,
  34. void* event_paths,
  35. const FSEventStreamEventFlags flags[],
  36. const FSEventStreamEventId event_ids[]);
  37. // Called from FSEventsCallback whenever there is a change to the paths.
  38. void OnFilePathsChanged(const std::vector<FilePath>& paths);
  39. // Called on the task_runner() thread to dispatch path events. Can't access
  40. // target_ and resolved_target_ directly as those are modified on the
  41. // libdispatch thread.
  42. void DispatchEvents(const std::vector<FilePath>& paths,
  43. const FilePath& target,
  44. const FilePath& resolved_target);
  45. // (Re-)Initialize the event stream to start reporting events from
  46. // |start_event|.
  47. void UpdateEventStream(FSEventStreamEventId start_event);
  48. // Returns true if resolving the target path got a different result than
  49. // last time it was done.
  50. bool ResolveTargetPath();
  51. // Report an error watching the given target.
  52. void ReportError(const FilePath& target);
  53. // Destroy the event stream.
  54. void DestroyEventStream();
  55. // Start watching the FSEventStream.
  56. void StartEventStream(FSEventStreamEventId start_event, const FilePath& path);
  57. // Callback to notify upon changes.
  58. // (Only accessed from the task_runner() thread.)
  59. FilePathWatcher::Callback callback_;
  60. // The dispatch queue on which the event stream is scheduled.
  61. ScopedDispatchObject<dispatch_queue_t> queue_;
  62. // Target path to watch (passed to callback).
  63. // (Only accessed from the libdispatch queue.)
  64. FilePath target_;
  65. // Target path with all symbolic links resolved.
  66. // (Only accessed from the libdispatch queue.)
  67. FilePath resolved_target_;
  68. // Backend stream we receive event callbacks from (strong reference).
  69. // (Only accessed from the libdispatch queue.)
  70. FSEventStreamRef fsevent_stream_;
  71. WeakPtrFactory<FilePathWatcherFSEvents> weak_factory_;
  72. DISALLOW_COPY_AND_ASSIGN(FilePathWatcherFSEvents);
  73. };
  74. } // namespace base
  75. #endif // BASE_FILES_FILE_PATH_WATCHER_FSEVENTS_H_