77#include < queue>
88#include < thread>
99#include < utility>
10+ #include < atomic> // Temporary workaround for LFS checkout. Code added to be reverted.
1011
1112extern " C" {
1213 #include < git2/sys/custom_tls.h>
@@ -81,8 +82,11 @@ namespace nodegit {
8182 : Event(CALLBACK_TYPE ), callback(initCallback)
8283 {}
8384
84- ThreadPool::Callback operator ()(ThreadPool::QueueCallbackFn queueCb, ThreadPool::Callback completedCb) {
85- return callback (queueCb, completedCb);
85+ // Temporary workaround for LFS checkout. Code modified to be reverted.
86+ // ThreadPool::Callback operator()(ThreadPool::QueueCallbackFn queueCb, ThreadPool::Callback completedCb) {
87+ // return callback(queueCb, completedCb);
88+ ThreadPool::Callback operator ()(ThreadPool::QueueCallbackFn queueCb, ThreadPool::Callback completedCb, bool isThreaded) {
89+ return callback (queueCb, completedCb, isThreaded);
8690 }
8791
8892 private:
@@ -102,6 +106,10 @@ namespace nodegit {
102106 // the Orchestrator's memory
103107 void WaitForThreadClose ();
104108
109+ // Temporary workaround for LFS checkout. Code added to be reverted.
110+ // Returns true if the task running spawned threads within libgit2
111+ bool IsGitThreaded () { return currentGitThreads > kInitialGitThreads ; }
112+
105113 static Nan::AsyncResource *GetCurrentAsyncResource ();
106114
107115 static const nodegit::Context *GetCurrentContext ();
@@ -139,6 +147,12 @@ namespace nodegit {
139147 PostCompletedEventToOrchestratorFn postCompletedEventToOrchestrator;
140148 TakeNextTaskFn takeNextTask;
141149 std::thread thread;
150+
151+ // Temporary workaround for LFS checkout. Code added to be reverted.
152+ static constexpr int kInitialGitThreads {0 };
153+ // Number of threads spawned internally by libgit2 to deal with
154+ // the task of this Executor instance. Defaults to kInitialGitThreads.
155+ std::atomic<int > currentGitThreads {kInitialGitThreads };
142156 };
143157
144158 Executor::Executor (
@@ -170,6 +184,9 @@ namespace nodegit {
170184
171185 WorkTask *workTask = static_cast <WorkTask *>(task.get ());
172186
187+ // Temporary workaround for LFS checkout. Code added to be reverted.
188+ currentGitThreads = kInitialGitThreads ;
189+
173190 currentAsyncResource = workTask->asyncResource ;
174191 currentCallbackErrorHandle = workTask->callbackErrorHandle ;
175192 workTask->callback ();
@@ -221,6 +238,8 @@ namespace nodegit {
221238 }
222239
223240 void *Executor::RetrieveTLSForLibgit2ChildThread () {
241+ // Temporary workaround for LFS checkout. Code added to be reverted.
242+ ++Executor::executor->currentGitThreads ;
224243 return Executor::executor;
225244 }
226245
@@ -230,6 +249,8 @@ namespace nodegit {
230249
231250 void Executor::TeardownTLSOnLibgit2ChildThread () {
232251 if (!isExecutorThread) {
252+ // Temporary workaround for LFS checkout. Code added to be reverted.
253+ --Executor::executor->currentGitThreads ;
233254 Executor::executor = nullptr ;
234255 }
235256 }
@@ -378,21 +399,46 @@ namespace nodegit {
378399 std::shared_ptr<std::condition_variable> callbackCondition (new std::condition_variable);
379400 bool hasCompleted = false ;
380401
381- LockMaster::TemporaryUnlock temporaryUnlock;
402+ // Temporary workaround for LFS checkout. Code removed to be reverted.
403+ // LockMaster::TemporaryUnlock temporaryUnlock;
404+
405+ // Temporary workaround for LFS checkout. Code added to be reverted.
406+ bool isWorkerThreaded = executor.IsGitThreaded ();
407+ ThreadPool::Callback callbackCompleted = []() {};
408+ if (!isWorkerThreaded) {
409+ callbackCompleted = [callbackCondition, callbackMutex, &hasCompleted]() {
410+ std::lock_guard<std::mutex> lock (*callbackMutex);
411+ hasCompleted = true ;
412+ callbackCondition->notify_one ();
413+ };
414+ }
415+ std::unique_ptr<LockMaster::TemporaryUnlock> temporaryUnlock {nullptr };
416+ if (!isWorkerThreaded) {
417+ temporaryUnlock = std::make_unique<LockMaster::TemporaryUnlock>();
418+ }
419+
382420 auto onCompletedCallback = (*callbackEvent)(
383421 [this ](ThreadPool::Callback callback, ThreadPool::Callback cancelCallback) {
384422 queueCallbackOnJSThread (callback, cancelCallback, false );
385423 },
424+ // Temporary workaround for LFS checkout. Code modified to be reverted.
425+ /*
386426 [callbackCondition, callbackMutex, &hasCompleted]() {
387427 std::lock_guard<std::mutex> lock(*callbackMutex);
388428 hasCompleted = true;
389429 callbackCondition->notify_one();
390430 }
431+ */
432+ callbackCompleted,
433+ isWorkerThreaded
391434 );
392435
393- std::unique_lock<std::mutex> lock (*callbackMutex);
394- while (!hasCompleted) callbackCondition->wait (lock);
395- onCompletedCallback ();
436+ // Temporary workaround for LFS checkout. Code modified to be reverted.
437+ if (!isWorkerThreaded) {
438+ std::unique_lock<std::mutex> lock (*callbackMutex);
439+ while (!hasCompleted) callbackCondition->wait (lock);
440+ onCompletedCallback ();
441+ }
396442 }
397443
398444 queueCallbackOnJSThread (
@@ -479,10 +525,6 @@ namespace nodegit {
479525
480526 void QueueCallbackOnJSThread (ThreadPool::Callback callback, ThreadPool::Callback cancelCallback, bool isWork);
481527
482- static void RunJSThreadCallbacksFromOrchestrator (uv_async_t *handle);
483-
484- void RunJSThreadCallbacksFromOrchestrator ();
485-
486528 static void RunLoopCallbacks (uv_async_t *handle);
487529
488530 void Shutdown (std::unique_ptr<AsyncContextCleanupHandle> cleanupHandle);
@@ -498,7 +540,6 @@ namespace nodegit {
498540
499541 private:
500542 bool isMarkedForDeletion;
501- nodegit::Context *currentContext;
502543
503544 struct JSThreadCallback {
504545 JSThreadCallback (ThreadPool::Callback callback, ThreadPool::Callback cancelCallback, bool isWork)
@@ -539,9 +580,9 @@ namespace nodegit {
539580 std::vector<Orchestrator> orchestrators;
540581 };
541582
583+ // context required to be passed to Orchestrators, but ThreadPoolImpl doesn't need to keep it
542584 ThreadPoolImpl::ThreadPoolImpl (int numberOfThreads, uv_loop_t *loop, nodegit::Context *context)
543585 : isMarkedForDeletion(false ),
544- currentContext(context),
545586 orchestratorJobMutex(new std::mutex),
546587 jsThreadCallbackMutex(new std::mutex)
547588 {
0 commit comments