code: func (v *txValidator) Validate(items []*txValidateItem) error {
  	if len(items) == 0 {
  		return nil
  	}
  
  	// Limit the number of goroutines to do script validation based on the
  	// number of processor cores.  This helps ensure the system stays
  	// reasonably responsive under heavy load.
  	maxGoRoutines := runtime.NumCPU() * 3
  	if maxGoRoutines <= 0 {
  		maxGoRoutines = 1
  	}
  	if maxGoRoutines > len(items) {
  		maxGoRoutines = len(items)
  	}
  
  	// Start up validation handlers that are used to asynchronously
  	// validate each transaction input.
  	for i := 0; i < maxGoRoutines; i++ {
  		go v.validateHandler()
  	}
  
  	// Validate each of the inputs.  The quit channel is closed when any
  	// errors occur so all processing goroutines exit regardless of which
  	// input had the validation error.
  	numInputs := len(items)
  	currentItem := 0
  	processedItems := 0
  	for processedItems < numInputs {
  		// Only send items while there are still items that need to
  		// be processed.  The select statement will never select a nil
  		// channel.
  		var validateChan chan *txValidateItem
  		var item *txValidateItem
  		if currentItem < numInputs {
  			validateChan = v.validateChan
  			item = items[currentItem]
  		}
  
  		select {
  		case validateChan <- item:
  			currentItem++
  
  		case err := <-v.resultChan:
  			processedItems++
  			if err != nil {
  				close(v.quitChan)
  				return err
  			}
  		}
  	}
  
  	close(v.quitChan)
  	return nil
  }
docs: // Validate validates the scripts for all of the passed transaction inputs using
  // multiple goroutines.