public PersistentStorageService(IOptionService optionService)
        {
            _optionService = optionService;

            _lookupAccessLock = new object();
            _lookup = new Dictionary<string, AbstractPersistentStorage>();

            _lastSolutionPath = null;

            _primarySolutionId = null;
            _primarySolutionStorage = null;
        }
        public void UnregisterPrimarySolution(SolutionId solutionId, bool synchronousShutdown)
        {
            AbstractPersistentStorage storage = null;
            lock (_lookupAccessLock)
            {
                if (_primarySolutionId == null)
                {
                    // primary solution is never registered or already unregistered
                    Contract.ThrowIfTrue(_primarySolutionStorage != null);
                    return;
                }

                Contract.ThrowIfFalse(_primarySolutionId == solutionId);

                _primarySolutionId = null;
                if (_primarySolutionStorage == null)
                {
                    // primary solution is registered but no C#/VB project was added
                    return;
                }

                storage = _primarySolutionStorage;
                _primarySolutionStorage = null;
            }

            if (storage != null)
            {
                if (synchronousShutdown)
                {
                    // dispose storage outside of the lock
                    storage.Dispose();
                }
                else
                {
                    // make it to shutdown asynchronously
                    Task.Run(() => storage.Dispose());
                }
            }
        }
 private void Release(AbstractPersistentStorage storage)
 {
     lock (_lookupAccessLock)
     {
         if (storage.ReleaseRefUnsafe())
         {
             _lookup.Remove(storage.SolutionFilePath);
             storage.Close();
         }
     }
 }
        private bool TryCreateEsentStorage(string workingFolderPath, string solutionPath, out AbstractPersistentStorage esentStorage)
        {
            esentStorage = null;
            EsentPersistentStorage esent = null;

            try
            {
                esent = new EsentPersistentStorage(_optionService, workingFolderPath, solutionPath, this.Release);
                esent.Initialize();

                esentStorage = esent;
                return true;
            }
            catch (EsentAccessDeniedException ex)
            {
                // esent db is already in use by someone.
                if (esent != null)
                {
                    esent.Close();
                }

                EsentLogger.LogException(ex);

                return false;
            }
            catch (Exception ex)
            {
                if (esent != null)
                {
                    esent.Close();
                }

                EsentLogger.LogException(ex);
            }

            try
            {
                if (esent != null)
                {
                    Directory.Delete(esent.EsentDirectory, recursive: true);
                }
            }
            catch
            {
                // somehow, we couldn't delete the directory.
            }

            return false;
        }
        private void RegisterPrimarySolutionStorageIfNeeded(Solution solution, AbstractPersistentStorage storage)
        {
            if (_primarySolutionStorage != null || solution.Id != _primarySolutionId)
            {
                return;
            }

            // hold onto the primary solution when it is used the first time.
            _primarySolutionStorage = storage;
            storage.AddRefUnsafe();
        }