You missed a semicolon after an assert, which broke asserts Mac builds. I fixed it in r367984.
From: cfe-commits <cfe-commits-boun...@lists.llvm.org> on behalf of Puyan Lotfi via cfe-commits <cfe-commits@lists.llvm.org> Reply-To: Puyan Lotfi <pu...@puyan.org> Date: Monday, August 5, 2019 at 10:11 PM To: "cfe-commits@lists.llvm.org" <cfe-commits@lists.llvm.org> Subject: r367979 - [clang][DirectoryWatcher] Adding llvm::Expected error handling to create. Author: zer0 Date: Mon Aug 5 22:12:23 2019 New Revision: 367979 URL: https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject-3Frev-3D367979-26view-3Drev&d=DwIGaQ&c=5VD0RTtNlTh3ycd41b3MUw&r=o3kDXzdBUE3ljQXKeTWOMw&m=6k2w1Mw8wKFqzKnFgq4r1I7Zmx7B-N-JdVMvtHYpjJs&s=GdHgTwHdRXipmG75D6eyJGuUUbCL0EMIl0YPYAY0y2U&e= Log: [clang][DirectoryWatcher] Adding llvm::Expected error handling to create. Prior to this patch Unix style errno error reporting from the inotify layer was used by DirectoryWatcher::create to simply return a nullptr on error. This would generally be ok, except that in LLVM we have much more robust error reporting through the facilities of llvm::Expected. The other critical thing I stumbled across was that the unit tests for DirectoryWatcher were not failing abruptly when inotify_init() was reporting an error, but would continue with the testing and eventually hit a deadlock in a pathological machine state (ie in the unit test, the return nullptr on ::create was ignored). Generally this pathological state never happens on any build bot, so it is totally understandable that it was overlooked, but on a Linux desktop running a dubious desktop environment (which I will not name) there is a chance that said desktop environment could use up enough inotify instances to exceed the user's limit. These are the conditions that led me to hit the deadlock I am addressing in this patch with more robust error handling. With the new llvm::Expected error handling when your system runs out of inotify instances for your user, the unit test will be forced to handle the error or crash and report the issue to the user instead of weirdly deadlocking on a condition variable wait. Differential Revision: https://urldefense.proofpoint.com/v2/url?u=https-3A__reviews.llvm.org_D65704&d=DwIGaQ&c=5VD0RTtNlTh3ycd41b3MUw&r=o3kDXzdBUE3ljQXKeTWOMw&m=6k2w1Mw8wKFqzKnFgq4r1I7Zmx7B-N-JdVMvtHYpjJs&s=vGtUV_-i1W7ejLSH8cWFnYlusAJMA8EK5kMTvuMmQB4&e= Modified: cfe/trunk/include/clang/DirectoryWatcher/DirectoryWatcher.h cfe/trunk/lib/DirectoryWatcher/default/DirectoryWatcher-not-implemented.cpp cfe/trunk/lib/DirectoryWatcher/linux/DirectoryWatcher-linux.cpp cfe/trunk/lib/DirectoryWatcher/mac/DirectoryWatcher-mac.cpp cfe/trunk/unittests/DirectoryWatcher/DirectoryWatcherTest.cpp Modified: cfe/trunk/include/clang/DirectoryWatcher/DirectoryWatcher.h URL: https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_cfe_trunk_include_clang_DirectoryWatcher_DirectoryWatcher.h-3Frev-3D367979-26r1-3D367978-26r2-3D367979-26view-3Ddiff&d=DwIGaQ&c=5VD0RTtNlTh3ycd41b3MUw&r=o3kDXzdBUE3ljQXKeTWOMw&m=6k2w1Mw8wKFqzKnFgq4r1I7Zmx7B-N-JdVMvtHYpjJs&s=VCfJ3mXkHYvO_8Iw35iGLiTPxX-OaQIrX9fUY22ukbw&e= ============================================================================== --- cfe/trunk/include/clang/DirectoryWatcher/DirectoryWatcher.h (original) +++ cfe/trunk/include/clang/DirectoryWatcher/DirectoryWatcher.h Mon Aug 5 22:12:23 2019 @@ -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)> Modified: cfe/trunk/lib/DirectoryWatcher/default/DirectoryWatcher-not-implemented.cpp URL: https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_cfe_trunk_lib_DirectoryWatcher_default_DirectoryWatcher-2Dnot-2Dimplemented.cpp-3Frev-3D367979-26r1-3D367978-26r2-3D367979-26view-3Ddiff&d=DwIGaQ&c=5VD0RTtNlTh3ycd41b3MUw&r=o3kDXzdBUE3ljQXKeTWOMw&m=6k2w1Mw8wKFqzKnFgq4r1I7Zmx7B-N-JdVMvtHYpjJs&s=kOGSMivkTUI-mqfkDLYmSGfQM8CSoTUydr4qZdtcaAc&e= ============================================================================== --- cfe/trunk/lib/DirectoryWatcher/default/DirectoryWatcher-not-implemented.cpp (original) +++ cfe/trunk/lib/DirectoryWatcher/default/DirectoryWatcher-not-implemented.cpp Mon Aug 5 22:12:23 2019 @@ -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 Modified: cfe/trunk/lib/DirectoryWatcher/linux/DirectoryWatcher-linux.cpp URL: https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_cfe_trunk_lib_DirectoryWatcher_linux_DirectoryWatcher-2Dlinux.cpp-3Frev-3D367979-26r1-3D367978-26r2-3D367979-26view-3Ddiff&d=DwIGaQ&c=5VD0RTtNlTh3ycd41b3MUw&r=o3kDXzdBUE3ljQXKeTWOMw&m=6k2w1Mw8wKFqzKnFgq4r1I7Zmx7B-N-JdVMvtHYpjJs&s=JukTCE-It3faGLTZEpsnCkN-RSCAfjthnHtk0Xh3PmA&e= ============================================================================== --- cfe/trunk/lib/DirectoryWatcher/linux/DirectoryWatcher-linux.cpp (original) +++ cfe/trunk/lib/DirectoryWatcher/linux/DirectoryWatcher-linux.cpp Mon Aug 5 22:12:23 2019 @@ -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::DirectoryWatcherL } // 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: #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, Modified: cfe/trunk/lib/DirectoryWatcher/mac/DirectoryWatcher-mac.cpp URL: https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_cfe_trunk_lib_DirectoryWatcher_mac_DirectoryWatcher-2Dmac.cpp-3Frev-3D367979-26r1-3D367978-26r2-3D367979-26view-3Ddiff&d=DwIGaQ&c=5VD0RTtNlTh3ycd41b3MUw&r=o3kDXzdBUE3ljQXKeTWOMw&m=6k2w1Mw8wKFqzKnFgq4r1I7Zmx7B-N-JdVMvtHYpjJs&s=T2eOFEXsVLLsAjg0xURecvVWyS6cEOOgHwW63xK5ZfY&e= ============================================================================== --- cfe/trunk/lib/DirectoryWatcher/mac/DirectoryWatcher-mac.cpp (original) +++ cfe/trunk/lib/DirectoryWatcher/mac/DirectoryWatcher-mac.cpp Mon Aug 5 22:12:23 2019 @@ -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 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); Modified: cfe/trunk/unittests/DirectoryWatcher/DirectoryWatcherTest.cpp URL: https://urldefense.proofpoint.com/v2/url?u=http-3A__llvm.org_viewvc_llvm-2Dproject_cfe_trunk_unittests_DirectoryWatcher_DirectoryWatcherTest.cpp-3Frev-3D367979-26r1-3D367978-26r2-3D367979-26view-3Ddiff&d=DwIGaQ&c=5VD0RTtNlTh3ycd41b3MUw&r=o3kDXzdBUE3ljQXKeTWOMw&m=6k2w1Mw8wKFqzKnFgq4r1I7Zmx7B-N-JdVMvtHYpjJs&s=4lOaG5iva-sTgUXlfX2eBaUzL1hMxauE0Pd2oW34fHk&e= ============================================================================== --- cfe/trunk/unittests/DirectoryWatcher/DirectoryWatcherTest.cpp (original) +++ cfe/trunk/unittests/DirectoryWatcher/DirectoryWatcherTest.cpp Mon Aug 5 22:12:23 2019 @@ -284,6 +284,7 @@ TEST(DirectoryWatcherTest, InitialScanSy TestConsumer.consume(Events, IsInitial); }, /*waitForInitialSync=*/true); + if (!DW) return; checkEventualResultWithTimeout(TestConsumer); } @@ -315,6 +316,7 @@ TEST(DirectoryWatcherTest, InitialScanAs 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, DeleteWatched TestConsumer.consume(Events, IsInitial); }, /*waitForInitialSync=*/true); + if (!DW) return; remove_directories(fixture.TestWatchedDir); @@ -431,6 +437,7 @@ TEST(DirectoryWatcherTest, InvalidatedWa TestConsumer.consume(Events, IsInitial); }, /*waitForInitialSync=*/true); + if (!DW) return; } // DW is destructed here. checkEventualResultWithTimeout(TestConsumer); _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org<mailto:cfe-commits@lists.llvm.org> https://urldefense.proofpoint.com/v2/url?u=https-3A__lists.llvm.org_cgi-2Dbin_mailman_listinfo_cfe-2Dcommits&d=DwIGaQ&c=5VD0RTtNlTh3ycd41b3MUw&r=o3kDXzdBUE3ljQXKeTWOMw&m=6k2w1Mw8wKFqzKnFgq4r1I7Zmx7B-N-JdVMvtHYpjJs&s=AvZ7rl6nzoSTyhQ1_rWF25r1kxnADHUAR7TvuiC3OE4&e=
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits