15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This module provides a way to monitor a file or directory for changes. 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef BASE_FILES_FILE_PATH_WATCHER_H_ 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define BASE_FILES_FILE_PATH_WATCHER_H_ 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/base_export.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/callback.h" 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/file_path.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/ref_counted.h" 15868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/message_loop/message_loop_proxy.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace base { 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// This class lets you register interest in changes on a FilePath. 20c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// The callback will get called whenever the file or directory referenced by the 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// FilePath is changed, including created or deleted. Due to limitations in the 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// underlying OS APIs, FilePathWatcher has slightly different semantics on OS X 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// than on Windows or Linux. FilePathWatcher on Linux and Windows will detect 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// modifications to files in a watched directory. FilePathWatcher on Mac will 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// detect the creation and deletion of files in a watched directory, but will 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// not detect modifications to those files. See file_path_watcher_kqueue.cc for 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// details. 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class BASE_EXPORT FilePathWatcher { 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Callback type for Watch(). |path| points to the file that was updated, 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // and |error| is true if the platform specific code detected an error. In 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // that case, the callback won't be invoked again. 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef base::Callback<void(const FilePath& path, bool error)> Callback; 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Used internally to encapsulate different members on different platforms. 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) class PlatformDelegate : public base::RefCountedThreadSafe<PlatformDelegate> { 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PlatformDelegate(); 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Start watching for the given |path| and notify |delegate| about changes. 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual bool Watch(const FilePath& path, 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool recursive, 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const Callback& callback) WARN_UNUSED_RESULT = 0; 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Stop watching. This is called from FilePathWatcher's dtor in order to 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // allow to shut down properly while the object is still alive. 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // It can be called from any thread. 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void Cancel() = 0; 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) friend class base::RefCountedThreadSafe<PlatformDelegate>; 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) friend class FilePathWatcher; 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~PlatformDelegate(); 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Stop watching. This is only called on the thread of the appropriate 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // message loop. Since it can also be called more than once, it should 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // check |is_cancelled()| to avoid duplicate work. 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void CancelOnMessageLoopThread() = 0; 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<base::MessageLoopProxy> message_loop() const { 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return message_loop_; 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void set_message_loop(base::MessageLoopProxy* loop) { 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) message_loop_ = loop; 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Must be called before the PlatformDelegate is deleted. 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void set_cancelled() { 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cancelled_ = true; 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool is_cancelled() const { 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return cancelled_; 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<base::MessageLoopProxy> message_loop_; 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool cancelled_; 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FilePathWatcher(); 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~FilePathWatcher(); 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // A callback that always cleans up the PlatformDelegate, either when executed 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // or when deleted without having been executed at all, as can happen during 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // shutdown. 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static void CancelWatch(const scoped_refptr<PlatformDelegate>& delegate); 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 91f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Returns true if the platform and OS version support recursive watches. 92f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) static bool RecursiveWatchAvailable(); 93f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Invokes |callback| whenever updates to |path| are detected. This should be 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // called at most once, and from a MessageLoop of TYPE_IO. Set |recursive| to 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // true, to watch |path| and its children. The callback will be invoked on 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // the same loop. Returns true on success. 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // 99f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Recursive watch is not supported on all platforms and file systems. 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Watch() will return false in the case of failure. 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool Watch(const FilePath& path, bool recursive, const Callback& callback); 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_refptr<PlatformDelegate> impl_; 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(FilePathWatcher); 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace base 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // BASE_FILES_FILE_PATH_WATCHER_H_ 112