in GVFS/GVFS.Virtualization/Background/BackgroundFileSystemTaskRunner.cs [160:257]
private void ProcessBackgroundTasks()
{
FileSystemTask backgroundTask;
while (true)
{
AcquireGVFSLockResult acquireLockResult = AcquireGVFSLockResult.ShuttingDown;
try
{
this.wakeUpThread.WaitOne();
if (this.isStopping)
{
return;
}
acquireLockResult = this.WaitToAcquireGVFSLock();
switch (acquireLockResult)
{
case AcquireGVFSLockResult.LockAcquired:
break;
case AcquireGVFSLockResult.ShuttingDown:
return;
default:
this.LogErrorAndExit("Invalid " + nameof(AcquireGVFSLockResult) + " result");
return;
}
this.RunCallbackUntilSuccess(this.preCallback, "PreCallback");
int tasksProcessed = 0;
while (this.backgroundTasks.TryPeek(out backgroundTask))
{
if (tasksProcessed % LogUpdateTaskThreshold == 0 &&
(tasksProcessed >= LogUpdateTaskThreshold || this.backgroundTasks.Count >= LogUpdateTaskThreshold))
{
this.LogTaskProcessingStatus(tasksProcessed);
}
if (this.isStopping)
{
// If we are stopping, then ProjFS has already been shut down
// Some of the queued background tasks may require ProjFS, and so it is unsafe to
// proceed. GVFS will resume any queued tasks next time it is mounted
return;
}
FileSystemTaskResult callbackResult = this.callback(backgroundTask);
switch (callbackResult)
{
case FileSystemTaskResult.Success:
this.backgroundTasks.DequeueAndFlush(backgroundTask);
++tasksProcessed;
break;
case FileSystemTaskResult.RetryableError:
if (!this.isStopping)
{
Thread.Sleep(ActionRetryDelayMS);
}
break;
case FileSystemTaskResult.FatalError:
this.LogErrorAndExit("Callback encountered fatal error, exiting process");
break;
default:
this.LogErrorAndExit("Invalid background operation result");
break;
}
}
if (tasksProcessed >= LogUpdateTaskThreshold)
{
EventMetadata metadata = new EventMetadata();
metadata.Add("Area", EtwArea);
metadata.Add("TasksProcessed", tasksProcessed);
metadata.Add(TracingConstants.MessageKey.InfoMessage, "Processing background tasks complete");
this.context.Tracer.RelatedEvent(EventLevel.Informational, "TaskProcessingStatus", metadata);
}
if (this.isStopping)
{
return;
}
}
catch (Exception e)
{
this.LogErrorAndExit($"{nameof(this.ProcessBackgroundTasks)} caught unhandled exception, exiting process", e);
}
finally
{
this.PerformPostTaskProcessing(acquireLockResult);
}
}
}