source: imaps-frontend/node_modules/@parcel/watcher/src/Backend.cc@ 0c6b92a

main
Last change on this file since 0c6b92a was 0c6b92a, checked in by stefan toskovski <stefantoska84@…>, 5 weeks ago

Pred finalna verzija

  • Property mode set to 100644
File size: 4.1 KB
Line 
1#ifdef FS_EVENTS
2#include "macos/FSEventsBackend.hh"
3#endif
4#ifdef WATCHMAN
5#include "watchman/WatchmanBackend.hh"
6#endif
7#ifdef WINDOWS
8#include "windows/WindowsBackend.hh"
9#endif
10#ifdef INOTIFY
11#include "linux/InotifyBackend.hh"
12#endif
13#ifdef KQUEUE
14#include "kqueue/KqueueBackend.hh"
15#endif
16#ifdef __wasm32__
17#include "wasm/WasmBackend.hh"
18#endif
19#include "shared/BruteForceBackend.hh"
20
21#include "Backend.hh"
22#include <unordered_map>
23
24static std::unordered_map<std::string, std::shared_ptr<Backend>> sharedBackends;
25
26std::shared_ptr<Backend> getBackend(std::string backend) {
27 // Use FSEvents on macOS by default.
28 // Use watchman by default if available on other platforms.
29 // Fall back to brute force.
30 #ifdef FS_EVENTS
31 if (backend == "fs-events" || backend == "default") {
32 return std::make_shared<FSEventsBackend>();
33 }
34 #endif
35 #ifdef WATCHMAN
36 if ((backend == "watchman" || backend == "default") && WatchmanBackend::checkAvailable()) {
37 return std::make_shared<WatchmanBackend>();
38 }
39 #endif
40 #ifdef WINDOWS
41 if (backend == "windows" || backend == "default") {
42 return std::make_shared<WindowsBackend>();
43 }
44 #endif
45 #ifdef INOTIFY
46 if (backend == "inotify" || backend == "default") {
47 return std::make_shared<InotifyBackend>();
48 }
49 #endif
50 #ifdef KQUEUE
51 if (backend == "kqueue" || backend == "default") {
52 return std::make_shared<KqueueBackend>();
53 }
54 #endif
55 #ifdef __wasm32__
56 if (backend == "wasm" || backend == "default") {
57 return std::make_shared<WasmBackend>();
58 }
59 #endif
60 if (backend == "brute-force" || backend == "default") {
61 return std::make_shared<BruteForceBackend>();
62 }
63
64 return nullptr;
65}
66
67std::shared_ptr<Backend> Backend::getShared(std::string backend) {
68 auto found = sharedBackends.find(backend);
69 if (found != sharedBackends.end()) {
70 return found->second;
71 }
72
73 auto result = getBackend(backend);
74 if (!result) {
75 return getShared("default");
76 }
77
78 result->run();
79 sharedBackends.emplace(backend, result);
80 return result;
81}
82
83void removeShared(Backend *backend) {
84 for (auto it = sharedBackends.begin(); it != sharedBackends.end(); it++) {
85 if (it->second.get() == backend) {
86 sharedBackends.erase(it);
87 break;
88 }
89 }
90
91 // Free up memory.
92 if (sharedBackends.size() == 0) {
93 sharedBackends.rehash(0);
94 }
95}
96
97void Backend::run() {
98 #ifndef __wasm32__
99 mThread = std::thread([this] () {
100 try {
101 start();
102 } catch (std::exception &err) {
103 handleError(err);
104 }
105 });
106
107 if (mThread.joinable()) {
108 mStartedSignal.wait();
109 }
110 #else
111 try {
112 start();
113 } catch (std::exception &err) {
114 handleError(err);
115 }
116 #endif
117}
118
119void Backend::notifyStarted() {
120 mStartedSignal.notify();
121}
122
123void Backend::start() {
124 notifyStarted();
125}
126
127Backend::~Backend() {
128 #ifndef __wasm32__
129 // Wait for thread to stop
130 if (mThread.joinable()) {
131 // If the backend is being destroyed from the thread itself, detach, otherwise join.
132 if (mThread.get_id() == std::this_thread::get_id()) {
133 mThread.detach();
134 } else {
135 mThread.join();
136 }
137 }
138 #endif
139}
140
141void Backend::watch(WatcherRef watcher) {
142 std::unique_lock<std::mutex> lock(mMutex);
143 auto res = mSubscriptions.find(watcher);
144 if (res == mSubscriptions.end()) {
145 try {
146 this->subscribe(watcher);
147 mSubscriptions.insert(watcher);
148 } catch (std::exception &err) {
149 unref();
150 throw;
151 }
152 }
153}
154
155void Backend::unwatch(WatcherRef watcher) {
156 std::unique_lock<std::mutex> lock(mMutex);
157 size_t deleted = mSubscriptions.erase(watcher);
158 if (deleted > 0) {
159 this->unsubscribe(watcher);
160 unref();
161 }
162}
163
164void Backend::unref() {
165 if (mSubscriptions.size() == 0) {
166 removeShared(this);
167 }
168}
169
170void Backend::handleWatcherError(WatcherError &err) {
171 unwatch(err.mWatcher);
172 err.mWatcher->notifyError(err);
173}
174
175void Backend::handleError(std::exception &err) {
176 std::unique_lock<std::mutex> lock(mMutex);
177 for (auto it = mSubscriptions.begin(); it != mSubscriptions.end(); it++) {
178 (*it)->notifyError(err);
179 }
180
181 removeShared(this);
182}
Note: See TracBrowser for help on using the repository browser.