summaryrefslogtreecommitdiffstats
path: root/clang/lib/DirectoryWatcher/mac/DirectoryWatcher-mac.cpp
diff options
context:
space:
mode:
authorReid Kleckner <rnk@google.com>2019-07-09 23:22:01 +0000
committerReid Kleckner <rnk@google.com>2019-07-09 23:22:01 +0000
commitabce8c457dd3de6b156756e547cc0eefb7653c79 (patch)
tree4e876876539fa08be4d6a6c1f72258e57a44a126 /clang/lib/DirectoryWatcher/mac/DirectoryWatcher-mac.cpp
parent1a697aa60722d71dfb7d6bd4d53fc361a6177fcc (diff)
downloadbcm5719-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.cpp233
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;
-}
OpenPOWER on IntegriCloud