file_path_watcher_fsevents.h 3.5 KB

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