| 
					
				 | 
			
			
				@@ -72,6 +72,8 @@ type Walker struct { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	// Optional progress tick interval which defines how often FolderScanProgress 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	// events are emitted. Negative number means disabled. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	ProgressTickIntervalS int 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	// Signals cancel from the outside - when closed, we should stop walking. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	Cancel chan struct{} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 } 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 type TempNamer interface { 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -121,7 +123,7 @@ func (w *Walker) Walk() (chan protocol.FileInfo, error) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	// We're not required to emit scan progress events, just kick off hashers, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	// and feed inputs directly from the walker. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	if w.ProgressTickIntervalS < 0 { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		newParallelHasher(w.Dir, w.BlockSize, w.Hashers, finishedChan, toHashChan, nil, nil) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		newParallelHasher(w.Dir, w.BlockSize, w.Hashers, finishedChan, toHashChan, nil, nil, w.Cancel) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		return finishedChan, nil 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -149,7 +151,7 @@ func (w *Walker) Walk() (chan protocol.FileInfo, error) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		realToHashChan := make(chan protocol.FileInfo) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		done := make(chan struct{}) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-		newParallelHasher(w.Dir, w.BlockSize, w.Hashers, finishedChan, realToHashChan, &progress, done) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+		newParallelHasher(w.Dir, w.BlockSize, w.Hashers, finishedChan, realToHashChan, &progress, done, w.Cancel) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		// A routine which actually emits the FolderScanProgress events 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		// every w.ProgressTicker ticks, until the hasher routines terminate. 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -168,13 +170,21 @@ func (w *Walker) Walk() (chan protocol.FileInfo, error) { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 						"current": current, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 						"total":   total, 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 					}) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				case <-w.Cancel: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					ticker.Stop() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+					return 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		}() 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+	loop: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		for _, file := range filesToHash { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			l.Debugln("real to hash:", file.Name) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			realToHashChan <- file 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			select { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			case realToHashChan <- file: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			case <-w.Cancel: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				break loop 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		close(realToHashChan) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 	}() 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -329,7 +339,11 @@ func (w *Walker) walkAndHashFiles(fchan, dchan chan protocol.FileInfo) filepath. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			l.Debugln("symlink changedb:", p, f) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			dchan <- f 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			select { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			case dchan <- f: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			case <-w.Cancel: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				return errors.New("cancelled") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			return skip 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		} 
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -363,7 +377,13 @@ func (w *Walker) walkAndHashFiles(fchan, dchan chan protocol.FileInfo) filepath. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				Modified: mtime.Unix(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			l.Debugln("dir:", p, f) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			dchan <- f 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			select { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			case dchan <- f: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			case <-w.Cancel: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				return errors.New("cancelled") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			return nil 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
	
		
			
				| 
					
				 | 
			
			
				@@ -406,7 +426,12 @@ func (w *Walker) walkAndHashFiles(fchan, dchan chan protocol.FileInfo) filepath. 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 				CachedSize: info.Size(), 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 			l.Debugln("to hash:", p, f) 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				-			fchan <- f 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+ 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			select { 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			case fchan <- f: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			case <-w.Cancel: 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+				return errors.New("cancelled") 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				+			} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		} 
			 | 
		
	
		
			
				 | 
				 | 
			
			
				  
			 | 
		
	
		
			
				 | 
				 | 
			
			
				 		return nil 
			 |