diff options
5 files changed, 34 insertions, 25 deletions
diff --git a/clang/include/clang/DirectoryWatcher/DirectoryWatcher.h b/clang/include/clang/DirectoryWatcher/DirectoryWatcher.h index e74443e0bc8..d2a16621639 100644 --- a/clang/include/clang/DirectoryWatcher/DirectoryWatcher.h +++ b/clang/include/clang/DirectoryWatcher/DirectoryWatcher.h @@ -11,6 +11,7 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/StringRef.h" +#include "llvm/Support/Error.h" #include <functional> #include <memory> #include <string> @@ -98,10 +99,11 @@ public: : Kind(Kind), Filename(Filename) {} }; - /// Returns nullptr if \param Path doesn't exist or isn't a directory. - /// Returns nullptr if OS kernel API told us we can't start watching. In such - /// case it's unclear whether just retrying has any chance to succeeed. - static std::unique_ptr<DirectoryWatcher> + /// Asserts if \param Path doesn't exist or isn't a directory. + /// Returns llvm::Expected Error if OS kernel API told us we can't start + /// watching. In such case it's unclear whether just retrying has any chance + /// to succeeed. + static llvm::Expected<std::unique_ptr<DirectoryWatcher>> create(llvm::StringRef Path, std::function<void(llvm::ArrayRef<DirectoryWatcher::Event> Events, bool IsInitial)> diff --git a/clang/lib/DirectoryWatcher/default/DirectoryWatcher-not-implemented.cpp b/clang/lib/DirectoryWatcher/default/DirectoryWatcher-not-implemented.cpp index e330ff06f50..200e540624a 100644 --- a/clang/lib/DirectoryWatcher/default/DirectoryWatcher-not-implemented.cpp +++ b/clang/lib/DirectoryWatcher/default/DirectoryWatcher-not-implemented.cpp @@ -11,9 +11,11 @@ using namespace llvm; using namespace clang; -std::unique_ptr<DirectoryWatcher> clang::DirectoryWatcher::create( +llvm::Expected<std::unique_ptr<DirectoryWatcher>> clang::DirectoryWatcher::create( StringRef Path, std::function<void(llvm::ArrayRef<DirectoryWatcher::Event>, bool)> Receiver, bool WaitForInitialSync) { - return nullptr; + return llvm::make_error<llvm::StringError>( + "DirectoryWatcher is not implemented for this platform!", + llvm::inconvertibleErrorCode()); }
\ No newline at end of file diff --git a/clang/lib/DirectoryWatcher/linux/DirectoryWatcher-linux.cpp b/clang/lib/DirectoryWatcher/linux/DirectoryWatcher-linux.cpp index 6998efbb5e8..8a5e76c521b 100644 --- a/clang/lib/DirectoryWatcher/linux/DirectoryWatcher-linux.cpp +++ b/clang/lib/DirectoryWatcher/linux/DirectoryWatcher-linux.cpp @@ -13,6 +13,7 @@ #include "llvm/ADT/ScopeExit.h" #include "llvm/Support/AlignOf.h" #include "llvm/Support/Errno.h" +#include "llvm/Support/Error.h" #include "llvm/Support/Mutex.h" #include "llvm/Support/Path.h" #include <atomic> @@ -320,16 +321,17 @@ DirectoryWatcherLinux::DirectoryWatcherLinux( } // namespace -std::unique_ptr<DirectoryWatcher> clang::DirectoryWatcher::create( +llvm::Expected<std::unique_ptr<DirectoryWatcher>> clang::DirectoryWatcher::create( StringRef Path, std::function<void(llvm::ArrayRef<DirectoryWatcher::Event>, bool)> Receiver, bool WaitForInitialSync) { - if (Path.empty()) - return nullptr; + assert(!Path.empty() && "Path.empty()"); const int InotifyFD = inotify_init1(IN_CLOEXEC); if (InotifyFD == -1) - return nullptr; + return llvm::make_error<llvm::StringError>( + std::string("inotify_init1() error: ") + strerror(errno), + llvm::inconvertibleErrorCode()); const int InotifyWD = inotify_add_watch( InotifyFD, Path.str().c_str(), @@ -340,12 +342,16 @@ std::unique_ptr<DirectoryWatcher> clang::DirectoryWatcher::create( #endif ); if (InotifyWD == -1) - return nullptr; + return llvm::make_error<llvm::StringError>( + std::string("inotify_add_watch() error: ") + strerror(errno), + llvm::inconvertibleErrorCode()); auto InotifyPollingStopper = SemaphorePipe::create(); if (!InotifyPollingStopper) - return nullptr; + return llvm::make_error<llvm::StringError>( + std::string("SemaphorePipe::create() error: ") + strerror(errno), + llvm::inconvertibleErrorCode()); return llvm::make_unique<DirectoryWatcherLinux>( Path, Receiver, WaitForInitialSync, InotifyFD, InotifyWD, diff --git a/clang/lib/DirectoryWatcher/mac/DirectoryWatcher-mac.cpp b/clang/lib/DirectoryWatcher/mac/DirectoryWatcher-mac.cpp index ae3cb614163..ade03c2bbc9 100644 --- a/clang/lib/DirectoryWatcher/mac/DirectoryWatcher-mac.cpp +++ b/clang/lib/DirectoryWatcher/mac/DirectoryWatcher-mac.cpp @@ -11,16 +11,13 @@ #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringRef.h" +#include "llvm/Support/Error.h" #include "llvm/Support/Path.h" #include <CoreServices/CoreServices.h> using namespace llvm; using namespace clang; -static FSEventStreamRef createFSEventStream( - StringRef Path, - std::function<void(llvm::ArrayRef<DirectoryWatcher::Event>, bool)>, - dispatch_queue_t); static void stopFSEventStream(FSEventStreamRef); namespace { @@ -153,8 +150,7 @@ FSEventStreamRef createFSEventStream( StringRef Path, std::function<void(llvm::ArrayRef<DirectoryWatcher::Event>, bool)> Receiver, dispatch_queue_t Queue) { - if (Path.empty()) - return nullptr; + assert(!Path.empty() && "Path.empty()"); CFMutableArrayRef PathsToWatch = [&]() { CFMutableArrayRef PathsToWatch = @@ -205,20 +201,16 @@ void stopFSEventStream(FSEventStreamRef EventStream) { FSEventStreamRelease(EventStream); } -std::unique_ptr<DirectoryWatcher> clang::DirectoryWatcher::create( +llvm::Expected<std::unique_ptr<DirectoryWatcher>> clang::DirectoryWatcher::create( StringRef Path, std::function<void(llvm::ArrayRef<DirectoryWatcher::Event>, bool)> Receiver, bool WaitForInitialSync) { dispatch_queue_t Queue = dispatch_queue_create("DirectoryWatcher", DISPATCH_QUEUE_SERIAL); - if (Path.empty()) - return nullptr; - + assert(!Path.empty() && "Path.empty()"); auto EventStream = createFSEventStream(Path, Receiver, Queue); - if (!EventStream) { - return nullptr; - } + assert(EventStream && "EventStream expected to be non-null.") std::unique_ptr<DirectoryWatcher> Result = llvm::make_unique<DirectoryWatcherMac>(EventStream, Receiver, Path); diff --git a/clang/unittests/DirectoryWatcher/DirectoryWatcherTest.cpp b/clang/unittests/DirectoryWatcher/DirectoryWatcherTest.cpp index 52a69616057..14ef3460327 100644 --- a/clang/unittests/DirectoryWatcher/DirectoryWatcherTest.cpp +++ b/clang/unittests/DirectoryWatcher/DirectoryWatcherTest.cpp @@ -284,6 +284,7 @@ TEST(DirectoryWatcherTest, InitialScanSync) { TestConsumer.consume(Events, IsInitial); }, /*waitForInitialSync=*/true); + if (!DW) return; checkEventualResultWithTimeout(TestConsumer); } @@ -315,6 +316,7 @@ TEST(DirectoryWatcherTest, InitialScanAsync) { TestConsumer.consume(Events, IsInitial); }, /*waitForInitialSync=*/false); + if (!DW) return; checkEventualResultWithTimeout(TestConsumer); } @@ -335,6 +337,7 @@ TEST(DirectoryWatcherTest, AddFiles) { TestConsumer.consume(Events, IsInitial); }, /*waitForInitialSync=*/true); + if (!DW) return; fixture.addFile("a"); fixture.addFile("b"); @@ -360,6 +363,7 @@ TEST(DirectoryWatcherTest, ModifyFile) { TestConsumer.consume(Events, IsInitial); }, /*waitForInitialSync=*/true); + if (!DW) return; // modify the file { @@ -390,6 +394,7 @@ TEST(DirectoryWatcherTest, DeleteFile) { TestConsumer.consume(Events, IsInitial); }, /*waitForInitialSync=*/true); + if (!DW) return; fixture.deleteFile("a"); @@ -411,6 +416,7 @@ TEST(DirectoryWatcherTest, DeleteWatchedDir) { TestConsumer.consume(Events, IsInitial); }, /*waitForInitialSync=*/true); + if (!DW) return; remove_directories(fixture.TestWatchedDir); @@ -431,6 +437,7 @@ TEST(DirectoryWatcherTest, InvalidatedWatcher) { TestConsumer.consume(Events, IsInitial); }, /*waitForInitialSync=*/true); + if (!DW) return; } // DW is destructed here. checkEventualResultWithTimeout(TestConsumer); |

