diff options
author | Reid Kleckner <rnk@google.com> | 2019-07-09 23:22:01 +0000 |
---|---|---|
committer | Reid Kleckner <rnk@google.com> | 2019-07-09 23:22:01 +0000 |
commit | abce8c457dd3de6b156756e547cc0eefb7653c79 (patch) | |
tree | 4e876876539fa08be4d6a6c1f72258e57a44a126 /clang/lib/DirectoryWatcher/mac/DirectoryWatcher-mac.cpp | |
parent | 1a697aa60722d71dfb7d6bd4d53fc361a6177fcc (diff) | |
download | bcm5719-llvm-abce8c457dd3de6b156756e547cc0eefb7653c79.tar.gz bcm5719-llvm-abce8c457dd3de6b156756e547cc0eefb7653c79.zip |
Revert [clang] DirectoryWatcher
This reverts r365574 (git commit 31babea94a3ed38a140540f2252cf043dacec1f7)
llvm-svn: 365581
Diffstat (limited to 'clang/lib/DirectoryWatcher/mac/DirectoryWatcher-mac.cpp')
-rw-r--r-- | clang/lib/DirectoryWatcher/mac/DirectoryWatcher-mac.cpp | 233 |
1 files changed, 0 insertions, 233 deletions
diff --git a/clang/lib/DirectoryWatcher/mac/DirectoryWatcher-mac.cpp b/clang/lib/DirectoryWatcher/mac/DirectoryWatcher-mac.cpp deleted file mode 100644 index 3df79ac48a4..00000000000 --- a/clang/lib/DirectoryWatcher/mac/DirectoryWatcher-mac.cpp +++ /dev/null @@ -1,233 +0,0 @@ -//===- DirectoryWatcher-mac.cpp - Mac-platform directory watching ---------===// -// -// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. -// See https://llvm.org/LICENSE.txt for license information. -// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -// -//===----------------------------------------------------------------------===// - -#include "DirectoryScanner.h" -#include "clang/DirectoryWatcher/DirectoryWatcher.h" - -#include "llvm/ADT/STLExtras.h" -#include "llvm/ADT/StringRef.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 { - -class DirectoryWatcherMac : public clang::DirectoryWatcher { -public: - DirectoryWatcherMac( - FSEventStreamRef EventStream, - std::function<void(llvm::ArrayRef<DirectoryWatcher::Event>, bool)> - Receiver, - llvm::StringRef WatchedDirPath) - : EventStream(EventStream), Receiver(Receiver), - WatchedDirPath(WatchedDirPath) {} - - ~DirectoryWatcherMac() override { - stopFSEventStream(EventStream); - EventStream = nullptr; - // Now it's safe to use Receiver as the only other concurrent use would have - // been in EventStream processing. - Receiver(DirectoryWatcher::Event( - DirectoryWatcher::Event::EventKind::WatcherGotInvalidated, ""), - false); - } - -private: - FSEventStreamRef EventStream; - std::function<void(llvm::ArrayRef<Event>, bool)> Receiver; - const std::string WatchedDirPath; -}; - -struct EventStreamContextData { - std::string WatchedPath; - std::function<void(llvm::ArrayRef<DirectoryWatcher::Event>, bool)> Receiver; - - EventStreamContextData( - std::string &&WatchedPath, - std::function<void(llvm::ArrayRef<DirectoryWatcher::Event>, bool)> - Receiver) - : WatchedPath(std::move(WatchedPath)), Receiver(Receiver) {} - - // Needed for FSEvents - static void dispose(const void *ctx) { - delete static_cast<const EventStreamContextData *>(ctx); - } -}; -} // namespace - -constexpr const FSEventStreamEventFlags StreamInvalidatingFlags = - kFSEventStreamEventFlagUserDropped | kFSEventStreamEventFlagKernelDropped | - kFSEventStreamEventFlagMustScanSubDirs; - -constexpr const FSEventStreamEventFlags ModifyingFileEvents = - kFSEventStreamEventFlagItemCreated | kFSEventStreamEventFlagItemRenamed | - kFSEventStreamEventFlagItemModified; - -static void eventStreamCallback(ConstFSEventStreamRef Stream, - void *ClientCallBackInfo, size_t NumEvents, - void *EventPaths, - const FSEventStreamEventFlags EventFlags[], - const FSEventStreamEventId EventIds[]) { - auto *ctx = static_cast<EventStreamContextData *>(ClientCallBackInfo); - - std::vector<DirectoryWatcher::Event> Events; - for (size_t i = 0; i < NumEvents; ++i) { - StringRef Path = ((const char **)EventPaths)[i]; - const FSEventStreamEventFlags Flags = EventFlags[i]; - - if (Flags & StreamInvalidatingFlags) { - Events.emplace_back(DirectoryWatcher::Event{ - DirectoryWatcher::Event::EventKind::WatcherGotInvalidated, ""}); - break; - } else if (!(Flags & kFSEventStreamEventFlagItemIsFile)) { - // Subdirectories aren't supported - if some directory got removed it - // must've been the watched directory itself. - if ((Flags & kFSEventStreamEventFlagItemRemoved) && - Path == ctx->WatchedPath) { - Events.emplace_back(DirectoryWatcher::Event{ - DirectoryWatcher::Event::EventKind::WatchedDirRemoved, ""}); - Events.emplace_back(DirectoryWatcher::Event{ - DirectoryWatcher::Event::EventKind::WatcherGotInvalidated, ""}); - break; - } - // No support for subdirectories - just ignore everything. - continue; - } else if (Flags & kFSEventStreamEventFlagItemRemoved) { - Events.emplace_back(DirectoryWatcher::Event::EventKind::Removed, - llvm::sys::path::filename(Path)); - continue; - } else if (Flags & ModifyingFileEvents) { - if (!getFileStatus(Path).hasValue()) { - Events.emplace_back(DirectoryWatcher::Event::EventKind::Removed, - llvm::sys::path::filename(Path)); - } else { - Events.emplace_back(DirectoryWatcher::Event::EventKind::Modified, - llvm::sys::path::filename(Path)); - } - continue; - } - - // default - Events.emplace_back(DirectoryWatcher::Event{ - DirectoryWatcher::Event::EventKind::WatcherGotInvalidated, ""}); - llvm_unreachable("Unknown FSEvent type."); - } - - if (!Events.empty()) { - ctx->Receiver(Events, /*IsInitial=*/false); - } -} - -FSEventStreamRef createFSEventStream( - StringRef Path, - std::function<void(llvm::ArrayRef<DirectoryWatcher::Event>, bool)> Receiver, - dispatch_queue_t Queue) { - if (Path.empty()) - return nullptr; - - CFMutableArrayRef PathsToWatch = [&]() { - CFMutableArrayRef PathsToWatch = - CFArrayCreateMutable(nullptr, 0, &kCFTypeArrayCallBacks); - CFStringRef CfPathStr = - CFStringCreateWithBytes(nullptr, (const UInt8 *)Path.data(), - Path.size(), kCFStringEncodingUTF8, false); - CFArrayAppendValue(PathsToWatch, CfPathStr); - CFRelease(CfPathStr); - return PathsToWatch; - }(); - - FSEventStreamContext Context = [&]() { - std::string RealPath; - { - SmallString<128> Storage; - StringRef P = llvm::Twine(Path).toNullTerminatedStringRef(Storage); - char Buffer[PATH_MAX]; - if (::realpath(P.begin(), Buffer) != nullptr) - RealPath = Buffer; - else - RealPath = Path; - } - - FSEventStreamContext Context; - Context.version = 0; - Context.info = new EventStreamContextData(std::move(RealPath), Receiver); - Context.retain = nullptr; - Context.release = EventStreamContextData::dispose; - Context.copyDescription = nullptr; - return Context; - }(); - - FSEventStreamRef Result = FSEventStreamCreate( - nullptr, eventStreamCallback, &Context, PathsToWatch, - kFSEventStreamEventIdSinceNow, /* latency in seconds */ 0.0, - kFSEventStreamCreateFlagFileEvents | kFSEventStreamCreateFlagNoDefer); - CFRelease(PathsToWatch); - - return Result; -} - -void stopFSEventStream(FSEventStreamRef EventStream) { - if (!EventStream) - return; - FSEventStreamStop(EventStream); - FSEventStreamInvalidate(EventStream); - FSEventStreamRelease(EventStream); -} - -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; - - auto EventStream = createFSEventStream(Path, Receiver, Queue); - if (!EventStream) { - return nullptr; - } - - std::unique_ptr<DirectoryWatcher> Result = - llvm::make_unique<DirectoryWatcherMac>(EventStream, Receiver, Path); - - // We need to copy the data so the lifetime is ok after a const copy is made - // for the block. - const std::string CopiedPath = Path; - - auto InitWork = ^{ - // We need to start watching the directory before we start scanning in order - // to not miss any event. By dispatching this on the same serial Queue as - // the FSEvents will be handled we manage to start watching BEFORE the - // inital scan and handling events ONLY AFTER the scan finishes. - FSEventStreamSetDispatchQueue(EventStream, Queue); - FSEventStreamStart(EventStream); - // We need to decrement the ref count for Queue as initialize() will return - // and FSEvents has incremented it. Since we have to wait for FSEvents to - // take ownership it's the easiest to do it here rather than main thread. - dispatch_release(Queue); - Receiver(getAsFileEvents(scanDirectory(CopiedPath)), /*IsInitial=*/true); - }; - - if (WaitForInitialSync) { - dispatch_sync(Queue, InitWork); - } else { - dispatch_async(Queue, InitWork); - } - - return Result; -} |