Exemple #1
0
        RecursiveDirectoryInfoQuery AcquireLockForQuery(FilePath path, bool getRemoteStatus)
        {
            RecursiveDirectoryInfoQuery rq;
            bool query = false;

            lock (queryLock) {
                rq = recursiveDirectoryQueryQueue.FirstOrDefault(q => q.Directory == path);
                if (rq == null)
                {
                    query = true;
                    var mre = new ManualResetEvent(false);
                    rq = new RecursiveDirectoryInfoQuery {
                        Directory       = path,
                        GetRemoteStatus = getRemoteStatus,
                        ResetEvent      = mre,
                        Count           = 1,
                    };
                }
                else
                {
                    Interlocked.Increment(ref rq.Count);
                }
            }
            if (query)
            {
                AddQuery(rq);
            }
            return(rq);
        }
Exemple #2
0
        public VersionInfo[] GetDirectoryVersionInfo(FilePath localDirectory, bool getRemoteStatus, bool recursive)
        {
            try {
                if (recursive)
                {
                    using (var mre = new ManualResetEvent(false)) {
                        var rq = new RecursiveDirectoryInfoQuery {
                            Directory       = localDirectory,
                            GetRemoteStatus = getRemoteStatus,
                            ResetEvent      = mre,
                        };
                        AddQuery(rq);
                        rq.ResetEvent.WaitOne();
                        return(rq.Result);
                    }
                }

                var status = infoCache.GetDirectoryStatus(localDirectory);
                if (status != null && !status.RequiresRefresh && (!getRemoteStatus || status.HasRemoteStatus))
                {
                    return(status.FileInfo);
                }

                // If there is no cached status, query it asynchronously
                DirectoryInfoQuery q = new DirectoryInfoQuery()
                {
                    Directory       = localDirectory,
                    GetRemoteStatus = getRemoteStatus
                };
                AddQuery(q);

                // If we have a status value but the value was invalidated (RequiresRefresh == true)
                // then we return the invalidated value while we start an async query to get the new one

                if (status != null && status.RequiresRefresh && (!getRemoteStatus || status.HasRemoteStatus))
                {
                    return(status.FileInfo);
                }
                return(new VersionInfo[0]);
            } finally {
                //Console.WriteLine ("GetDirectoryVersionInfo " + localDirectory + " - " + (DateTime.Now - now).TotalMilliseconds);
            }
        }
Exemple #3
0
        public VersionInfo[] GetDirectoryVersionInfo(FilePath localDirectory, bool getRemoteStatus, bool recursive)
        {
            try {
                if (recursive)
                {
                    RecursiveDirectoryInfoQuery rq = AcquireLockForQuery(localDirectory, getRemoteStatus);
                    rq.ResetEvent.WaitOne();

                    lock (queryLock)
                        if (Interlocked.Decrement(ref rq.Count) == 0)
                        {
                            rq.ResetEvent.Dispose();
                        }
                    return(rq.Result);
                }

                var status = infoCache.GetDirectoryStatus(localDirectory);
                if (status != null && !status.RequiresRefresh && (!getRemoteStatus || status.HasRemoteStatus))
                {
                    return(status.FileInfo);
                }

                // If there is no cached status, query it asynchronously
                DirectoryInfoQuery q = new DirectoryInfoQuery()
                {
                    Directory       = localDirectory,
                    GetRemoteStatus = getRemoteStatus
                };
                AddQuery(q);

                // If we have a status value but the value was invalidated (RequiresRefresh == true)
                // then we return the invalidated value while we start an async query to get the new one

                if (status != null && status.RequiresRefresh && (!getRemoteStatus || status.HasRemoteStatus))
                {
                    return(status.FileInfo);
                }
                return(new VersionInfo[0]);
            } finally {
                //Console.WriteLine ("GetDirectoryVersionInfo " + localDirectory + " - " + (DateTime.Now - now).TotalMilliseconds);
            }
        }
		void RunQueries (object ob)
		{
		//	DateTime t = DateTime.Now;
			//	Console.WriteLine ("RunQueries started");
			VersionInfoQuery [] fileQueryQueueClone;
			DirectoryInfoQuery [] directoryQueryQueueClone;
			RecursiveDirectoryInfoQuery [] recursiveDirectoryQueryQueueClone = new RecursiveDirectoryInfoQuery[0];
			try {
				while (true) {
					lock (queryLock) {
						if (fileQueryQueue.Count == 0 &&
							directoryQueryQueue.Count == 0 &&
							recursiveDirectoryQueryQueue.Count == 0) {
							queryRunning = false;
							return;
						}

						fileQueryQueueClone = fileQueryQueue.ToArray ();
						fileQueryQueue.Clear ();
						filesInQueryQueue.Clear ();

						directoryQueryQueueClone = directoryQueryQueue.ToArray ();
						directoriesInQueryQueue.Clear ();
						directoryQueryQueue.Clear ();

						recursiveDirectoryQueryQueueClone = recursiveDirectoryQueryQueue.ToArray ();
						recursiveDirectoriesInQueryQueue.Clear ();
						recursiveDirectoryQueryQueue.Clear ();
					}

					// Ensure we do not execute this with the query lock held, otherwise the IDE can hang while trying to add
					// new queries to the queue while long-running VCS operations are being performed
					var groups = fileQueryQueueClone.GroupBy (q => (q.QueryFlags & VersionInfoQueryFlags.IncludeRemoteStatus) != 0);
					foreach (var group in groups) {
						var status = OnGetVersionInfo (group.SelectMany (q => q.Paths), group.Key);
						infoCache.SetStatus (status);
					}

					foreach (var item in directoryQueryQueueClone) {
						var status = OnGetDirectoryVersionInfo (item.Directory, item.GetRemoteStatus, false);
						infoCache.SetDirectoryStatus (item.Directory, status, item.GetRemoteStatus);
					}

					foreach (var item in recursiveDirectoryQueryQueueClone) {
						try {
							item.Result = OnGetDirectoryVersionInfo (item.Directory, item.GetRemoteStatus, true);
						} finally {
							item.ResetEvent.Set ();
						}
					}
				}
			} catch (Exception ex) {
				LoggingService.LogError ("Version control status query failed", ex);

				//Release all items in current batch
				foreach (var item in recursiveDirectoryQueryQueueClone)
					item.ResetEvent.Set ();

				lock (queryLock) {
					queryRunning = false;
						
					fileQueryQueue.Clear ();
					filesInQueryQueue.Clear ();

					directoriesInQueryQueue.Clear ();
					directoryQueryQueue.Clear ();

					recursiveDirectoryQueryQueueClone = recursiveDirectoryQueryQueue.ToArray ();
					recursiveDirectoriesInQueryQueue.Clear ();
					recursiveDirectoryQueryQueue.Clear ();
				}

				//Release newly pending
				foreach (var item in recursiveDirectoryQueryQueueClone)
					item.ResetEvent.Set ();
			}
			//Console.WriteLine ("RunQueries finished - " + (DateTime.Now - t).TotalMilliseconds);
		}
		RecursiveDirectoryInfoQuery AcquireLockForQuery (FilePath path, bool getRemoteStatus)
		{
			RecursiveDirectoryInfoQuery rq;
			bool query = false;
			lock (queryLock) {
				rq = recursiveDirectoryQueryQueue.FirstOrDefault (q => q.Directory == path);
				if (rq == null) {
					query = true;
					var mre = new ManualResetEvent (false);
					rq = new RecursiveDirectoryInfoQuery {
						Directory = path,
						GetRemoteStatus = getRemoteStatus,
						ResetEvent = mre,
						Count = 1,
					};
				} else
					Interlocked.Increment (ref rq.Count);
			}
			if (query)
				AddQuery (rq);
			return rq;
		}
Exemple #6
0
        void RunQueries(object ob)
        {
            //	DateTime t = DateTime.Now;
            //	Console.WriteLine ("RunQueries started");
            VersionInfoQuery []            fileQueryQueueClone;
            DirectoryInfoQuery []          directoryQueryQueueClone;
            RecursiveDirectoryInfoQuery [] recursiveDirectoryQueryQueueClone = new RecursiveDirectoryInfoQuery[0];
            try {
                while (true)
                {
                    lock (queryLock) {
                        if (fileQueryQueue.Count == 0 &&
                            directoryQueryQueue.Count == 0 &&
                            recursiveDirectoryQueryQueue.Count == 0)
                        {
                            queryRunning = false;
                            return;
                        }

                        fileQueryQueueClone = fileQueryQueue.ToArray();
                        fileQueryQueue.Clear();
                        filesInQueryQueue.Clear();

                        directoryQueryQueueClone = directoryQueryQueue.ToArray();
                        directoriesInQueryQueue.Clear();
                        directoryQueryQueue.Clear();

                        recursiveDirectoryQueryQueueClone = recursiveDirectoryQueryQueue.ToArray();
                        recursiveDirectoriesInQueryQueue.Clear();
                        recursiveDirectoryQueryQueue.Clear();
                    }

                    // Ensure we do not execute this with the query lock held, otherwise the IDE can hang while trying to add
                    // new queries to the queue while long-running VCS operations are being performed
                    var groups = fileQueryQueueClone.GroupBy(q => (q.QueryFlags & VersionInfoQueryFlags.IncludeRemoteStatus) != 0);
                    foreach (var group in groups)
                    {
                        if (Disposed)
                        {
                            break;
                        }
                        var status = OnGetVersionInfo(group.SelectMany(q => q.Paths), group.Key);
                        infoCache.SetStatus(status);
                    }

                    foreach (var item in directoryQueryQueueClone)
                    {
                        if (Disposed)
                        {
                            break;
                        }
                        var status = OnGetDirectoryVersionInfo(item.Directory, item.GetRemoteStatus, false);
                        infoCache.SetDirectoryStatus(item.Directory, status, item.GetRemoteStatus);
                    }

                    foreach (var item in recursiveDirectoryQueryQueueClone)
                    {
                        try {
                            if (Disposed)
                            {
                                continue;
                            }
                            item.Result = OnGetDirectoryVersionInfo(item.Directory, item.GetRemoteStatus, true);
                        } finally {
                            item.ResetEvent.Set();
                        }
                    }
                }
            } catch (Exception ex) {
                LoggingService.LogError("Version control status query failed", ex);

                //Release all items in current batch
                foreach (var item in recursiveDirectoryQueryQueueClone)
                {
                    item.ResetEvent.Set();
                }

                lock (queryLock) {
                    queryRunning = false;

                    fileQueryQueue.Clear();
                    filesInQueryQueue.Clear();

                    directoriesInQueryQueue.Clear();
                    directoryQueryQueue.Clear();

                    recursiveDirectoryQueryQueueClone = recursiveDirectoryQueryQueue.ToArray();
                    recursiveDirectoriesInQueryQueue.Clear();
                    recursiveDirectoryQueryQueue.Clear();
                }

                //Release newly pending
                foreach (var item in recursiveDirectoryQueryQueueClone)
                {
                    item.ResetEvent.Set();
                }
            }
            //Console.WriteLine ("RunQueries finished - " + (DateTime.Now - t).TotalMilliseconds);
        }
		public VersionInfo[] GetDirectoryVersionInfo (FilePath localDirectory, bool getRemoteStatus, bool recursive)
		{
			try {
				if (recursive) {
					using (var mre = new ManualResetEvent (false)) {
						var rq = new RecursiveDirectoryInfoQuery {
							Directory = localDirectory,
							GetRemoteStatus = getRemoteStatus,
							ResetEvent = mre,
						};
						AddQuery (rq);
						rq.ResetEvent.WaitOne ();
						return rq.Result;
					}
				}

				var status = infoCache.GetDirectoryStatus (localDirectory);
				if (status != null && !status.RequiresRefresh && (!getRemoteStatus || status.HasRemoteStatus))
					return status.FileInfo;

				// If there is no cached status, query it asynchronously
				DirectoryInfoQuery q = new DirectoryInfoQuery () {
					Directory = localDirectory,
					GetRemoteStatus = getRemoteStatus
				};
				AddQuery (q);

				// If we have a status value but the value was invalidated (RequiresRefresh == true)
				// then we return the invalidated value while we start an async query to get the new one

				if (status != null && status.RequiresRefresh && (!getRemoteStatus || status.HasRemoteStatus))
					return status.FileInfo;
				return new VersionInfo[0];
			} finally {
				//Console.WriteLine ("GetDirectoryVersionInfo " + localDirectory + " - " + (DateTime.Now - now).TotalMilliseconds);
			}
		}