Example #1
0
        public static void BeginAddOrUpdatePaths(IEnumerable <string> basePaths, bool skipFunctionBodies = false, ParseFinishedHandler finishedHandler = null)
        {
            if (basePaths == null)
            {
                throw new ArgumentNullException("basePaths");
            }

            if (System.Diagnostics.Debugger.IsAttached)
            {
                Console.WriteLine("BeginAddOrUpdatePaths: ");
                foreach (var p in basePaths)
                {
                    Console.WriteLine(p);
                }
                Console.WriteLine("---------");
            }

            GC.Collect();

            parseCompletedEvent.Reset();
            stopParsing = false;

            var c = basePaths.Count();

            if (c == 0)
            {
                var im = new StatIntermediate();
                if (finishedHandler != null)
                {
                    im.parseSubTasksUntilFinished.Add(new ParseSubtaskContainer(1, finishedHandler));
                }
                im.completed.Set();
                Interlocked.Increment(ref parsingThreads);
                noticeFinish(new ParseIntermediate(im, null, null));
                return;
            }

            var countObj = new ParseSubtaskContainer(c, finishedHandler);

            foreach (var path in basePaths)
            {
                Interlocked.Increment(ref parsingThreads);
                basePathQueue.Push(new PathQueueArgs(path, skipFunctionBodies, countObj));
            }
            preparationThreadStartEvent.Set();

            LaunchPreparationThread();
        }
		static void preparationTh ()
		{
			while (true) {
				if (basePathQueue.IsEmpty && !preparationThreadStartEvent.WaitOne (ThreadWaitTimeout))
					return;

				PathQueueArgs tup;
				while (basePathQueue.TryPop(out tup)) {
					if (stopParsing)
						break;

					var path = tup.basePath;
					if (!Directory.Exists (path))
						continue; // Is it okay to directly skip it w/o calling noticeFinished?

					StatIntermediate statIm;

					// Check if path is being parsed currently.
					{
						criticalPreparationSection.WaitOne ();

						if (ParseStatistics.TryGetValue (path, out statIm)) {
							if(tup.finished_untilCount != null)
								statIm.parseSubTasksUntilFinished.Add (tup.finished_untilCount);

							if (Interlocked.Decrement (ref parsingThreads) < 1)
								throw new InvalidOperationException ("Race-condition during parse process: There must be two or more parse tasks active!");

							criticalPreparationSection.Set ();
							continue;
						}

						ParseStatistics [path] = statIm = new StatIntermediate { 
							skipFunctionBodies = tup.skipFunctionBodies, 
							basePath = path,
						};
						if(tup.finished_untilCount != null)
							statIm.parseSubTasksUntilFinished.Add (tup.finished_untilCount);

						criticalPreparationSection.Set ();
					}

					// Check if it's necessary to reparse the directory
					RootPackage oldRoot;
					if (ParsedDirectories.TryGetValue (path, out oldRoot) &&
						oldRoot.LastParseTime >= Directory.GetLastWriteTimeUtc (path)) {
						noticeFinish (new ParseIntermediate (statIm, oldRoot, string.Empty));
						continue;
					}

					statIm.sw.Restart ();

					//ISSUE: wild card character ? seems to behave differently across platforms
					// msdn: -> Exactly zero or one character.
					// monodocs: -> Exactly one character.
					var files = Directory.GetFiles (path, "*.d", SearchOption.AllDirectories);
					var ifiles = Directory.GetFiles (path, "*.di", SearchOption.AllDirectories);

					statIm.totalFiles = statIm.remainingFiles = files.Length + ifiles.Length;
				
					var newRoot = new RootPackage {
						LastParseTime = Directory.GetLastWriteTimeUtc(path)
					};

					if (statIm.totalFiles == 0) {
						noticeFinish (new ParseIntermediate (statIm, newRoot, string.Empty));
						continue;
					}

					parseThreadStartEvent.Set ();

					LaunchParseThreads ();

					if (files.Length != 0)
						foreach (string file in files)
							queue.Push (new ParseIntermediate (statIm, newRoot, file));

					if (ifiles.Length != 0)
						foreach (string ifile in ifiles)
							queue.Push (new ParseIntermediate (statIm, newRoot,ifile));

					parseThreadStartEvent.Reset ();
				}
			}
		}
		public static void BeginAddOrUpdatePaths (IEnumerable<string> basePaths, bool skipFunctionBodies = false, ParseFinishedHandler finishedHandler = null)
		{
			if (basePaths == null)
				throw new ArgumentNullException ("basePaths");

			if (System.Diagnostics.Debugger.IsAttached) {
				Console.WriteLine ("BeginAddOrUpdatePaths: ");
				foreach (var p in basePaths)
					Console.WriteLine (p);
				Console.WriteLine ("---------");
			}

			GC.Collect ();

			parseCompletedEvent.Reset ();
			stopParsing = false;

			var c = basePaths.Count ();

			if (c == 0) {
				var im = new StatIntermediate();
				if(finishedHandler!=null)
					im.parseSubTasksUntilFinished.Add (new ParseSubtaskContainer(1,finishedHandler));
				im.completed.Set ();
				Interlocked.Increment (ref parsingThreads);
				noticeFinish (new ParseIntermediate (im, null, null));
				return;
			}

			var countObj = new ParseSubtaskContainer (c, finishedHandler);

			foreach (var path in basePaths) {
				Interlocked.Increment (ref parsingThreads);
				basePathQueue.Push (new PathQueueArgs (path, skipFunctionBodies, countObj));
			}
			preparationThreadStartEvent.Set ();

			LaunchPreparationThread ();
		}
			public ParseIntermediate (StatIntermediate im, RootPackage r, string f)
			{
				this.im = im;
				root = r;
				file = f;
			}
Example #5
0
        static void preparationTh()
        {
            while (true)
            {
                if (basePathQueue.IsEmpty && !preparationThreadStartEvent.WaitOne(ThreadWaitTimeout))
                {
                    return;
                }

                PathQueueArgs tup;
                while (basePathQueue.TryPop(out tup))
                {
                    if (stopParsing)
                    {
                        break;
                    }

                    var path = tup.basePath;
                    if (!Directory.Exists(path))
                    {
                        continue;                         // Is it okay to directly skip it w/o calling noticeFinished?
                    }
                    StatIntermediate statIm;

                    // Check if path is being parsed currently.
                    {
                        criticalPreparationSection.WaitOne();

                        if (ParseStatistics.TryGetValue(path, out statIm))
                        {
                            if (tup.finished_untilCount != null)
                            {
                                statIm.parseSubTasksUntilFinished.Add(tup.finished_untilCount);
                            }

                            if (Interlocked.Decrement(ref parsingThreads) < 1)
                            {
                                throw new InvalidOperationException("Race-condition during parse process: There must be two or more parse tasks active!");
                            }

                            criticalPreparationSection.Set();
                            continue;
                        }

                        ParseStatistics [path] = statIm = new StatIntermediate {
                            skipFunctionBodies = tup.skipFunctionBodies,
                            basePath           = path,
                        };
                        if (tup.finished_untilCount != null)
                        {
                            statIm.parseSubTasksUntilFinished.Add(tup.finished_untilCount);
                        }

                        criticalPreparationSection.Set();
                    }

                    // Check if it's necessary to reparse the directory
                    RootPackage oldRoot;
                    if (ParsedDirectories.TryGetValue(path, out oldRoot) &&
                        oldRoot.LastParseTime >= Directory.GetLastWriteTimeUtc(path))
                    {
                        noticeFinish(new ParseIntermediate(statIm, oldRoot, string.Empty));
                        continue;
                    }

                    statIm.sw.Restart();

                    //ISSUE: wild card character ? seems to behave differently across platforms
                    // msdn: -> Exactly zero or one character.
                    // monodocs: -> Exactly one character.
                    var files  = Directory.GetFiles(path, "*.d", SearchOption.AllDirectories);
                    var ifiles = Directory.GetFiles(path, "*.di", SearchOption.AllDirectories);

                    statIm.totalFiles = statIm.remainingFiles = files.Length + ifiles.Length;

                    var newRoot = new RootPackage {
                        LastParseTime = Directory.GetLastWriteTimeUtc(path)
                    };

                    if (statIm.totalFiles == 0)
                    {
                        noticeFinish(new ParseIntermediate(statIm, newRoot, string.Empty));
                        continue;
                    }

                    parseThreadStartEvent.Set();

                    LaunchParseThreads();

                    if (files.Length != 0)
                    {
                        foreach (string file in files)
                        {
                            queue.Push(new ParseIntermediate(statIm, newRoot, file));
                        }
                    }

                    if (ifiles.Length != 0)
                    {
                        foreach (string ifile in ifiles)
                        {
                            queue.Push(new ParseIntermediate(statIm, newRoot, ifile));
                        }
                    }

                    parseThreadStartEvent.Reset();
                }
            }
        }
Example #6
0
 public ParseIntermediate(StatIntermediate im, RootPackage r, string f)
 {
     this.im = im;
     root    = r;
     file    = f;
 }