func (computeSystem *System) WaitTimeout(timeout time.Duration) error {
	title := "hcsshim::ComputeSystem::WaitTimeout ID=" + computeSystem.ID()
	logrus.Debugf(title)
	err := waitForNotification(computeSystem.callbackNumber, hcsNotificationSystemExited, &timeout)
	if err != nil {
		return makeSystemError(computeSystem, "WaitTimeout", "", err, nil)
	}
	logrus.Debugf(title + " succeeded")
	return nil
}
WaitTimeout synchronously waits for the compute system to terminate or the duration to elapse.
If the timeout expires, IsTimeout(err) == true
package hcs
import (
	"encoding/json"
	"os"
	"strconv"
	"sync"
	"syscall"
	"time"
	"github.com/Microsoft/hcsshim/internal/interop"
	"github.com/Microsoft/hcsshim/internal/schema1"
	"github.com/Microsoft/hcsshim/internal/timeout"
	"github.com/sirupsen/logrus"
)
var currentContainerStarts containerStarts
type containerStarts struct {
	maxParallel int
	inProgress  int
	sync.Mutex
}
func init() {
	mpsS := os.Getenv("HCSSHIM_MAX_PARALLEL_START")
	if len(mpsS) > 0 {
		mpsI, err := strconv.Atoi(mpsS)
		if err != nil || mpsI < 0 {
			return
		}
		currentContainerStarts.maxParallel = mpsI
	}
}
type System struct {
	handleLock     sync.RWMutex
	handle         hcsSystem
	id             string
	callbackNumber uintptr
}
func CreateComputeSystem(id string, hcsDocumentInterface interface{}) (*System, error) {
	operation := "CreateComputeSystem"
	title := "hcsshim::" + operation
	computeSystem := &System{
		id: id,
	}
	hcsDocumentB, err := json.Marshal(hcsDocumentInterface)
	if err != nil {
		return nil, err
	}
	hcsDocument := string(hcsDocumentB)
	logrus.Debugf(title+" ID=%s config=%s", id, hcsDocument)
	var (
		resultp  *uint16
		identity syscall.Handle
	)
	createError := hcsCreateComputeSystem(id, hcsDocument, identity, &computeSystem.handle, &resultp)
	if createError == nil || IsPending(createError) {
		if err := computeSystem.registerCallback(); err != nil {
			computeSystem.Terminate()
			return nil, makeSystemError(computeSystem, operation, "", err, nil)
		}
	}
	events, err := processAsyncHcsResult(createError, resultp, computeSystem.callbackNumber, hcsNotificationSystemCreateCompleted, &timeout.Duration)
	if err != nil {
		if err == ErrTimeout {
			computeSystem.Terminate()
		}
		return nil, makeSystemError(computeSystem, operation, hcsDocument, err, events)
	}
	logrus.Debugf(title+" succeeded id=%s handle=%d", id, computeSystem.handle)
	return computeSystem, nil
}
func OpenComputeSystem(id string) (*System, error) {
	operation := "OpenComputeSystem"
	title := "hcsshim::" + operation
	logrus.Debugf(title+" ID=%s", id)
	computeSystem := &System{
		id: id,
	}
	var (
		handle  hcsSystem
		resultp *uint16
	)
	err := hcsOpenComputeSystem(id, &handle, &resultp)
	events := processHcsResult(resultp)
	if err != nil {
		return nil, makeSystemError(computeSystem, operation, "", err, events)
	}
	computeSystem.handle = handle
	if err := computeSystem.registerCallback(); err != nil {
		return nil, makeSystemError(computeSystem, operation, "", err, nil)
	}
	logrus.Debugf(title+" succeeded id=%s handle=%d", id, handle)
	return computeSystem, nil
}
func GetComputeSystems(q schema1.ComputeSystemQuery) ([]schema1.ContainerProperties, error) {
	operation := "GetComputeSystems"
	title := "hcsshim::" + operation
	queryb, err := json.Marshal(q)
	if err != nil {
		return nil, err
	}
	query := string(queryb)
	logrus.Debugf(title+" query=%s", query)
	var (
		resultp         *uint16
		computeSystemsp *uint16
	)
	err = hcsEnumerateComputeSystems(query, &computeSystemsp, &resultp)
	events := processHcsResult(resultp)
	if err != nil {
		return nil, &HcsError{Op: operation, Err: err, Events: events}
	}
	if computeSystemsp == nil {
		return nil, ErrUnexpectedValue
	}
	computeSystemsRaw := interop.ConvertAndFreeCoTaskMemBytes(computeSystemsp)
	computeSystems := []schema1.ContainerProperties{}
	if err := json.Unmarshal(computeSystemsRaw, &computeSystems); err != nil {
		return nil, err
	}
	logrus.Debugf(title + " succeeded")
	return computeSystems, nil
}
func (computeSystem *System) Start() error {
	computeSystem.handleLock.RLock()
	defer computeSystem.handleLock.RUnlock()
	title := "hcsshim::ComputeSystem::Start ID=" + computeSystem.ID()
	logrus.Debugf(title)
	if computeSystem.handle == 0 {
		return makeSystemError(computeSystem, "Start", "", ErrAlreadyClosed, nil)
	}
	if currentContainerStarts.maxParallel > 0 {
		for {
			currentContainerStarts.Lock()
			if currentContainerStarts.inProgress < currentContainerStarts.maxParallel {
				currentContainerStarts.inProgress++
				currentContainerStarts.Unlock()
				break
			}
			if currentContainerStarts.inProgress == currentContainerStarts.maxParallel {
				currentContainerStarts.Unlock()
				time.Sleep(100 * time.Millisecond)
			}
		}
		defer func() {
			currentContainerStarts.Lock()
			currentContainerStarts.inProgress--
			currentContainerStarts.Unlock()
		}()
	}
	var resultp *uint16
	err := hcsStartComputeSystem(computeSystem.handle, "", &resultp)
	events, err := processAsyncHcsResult(err, resultp, computeSystem.callbackNumber, hcsNotificationSystemStartCompleted, &timeout.Duration)
	if err != nil {
		return makeSystemError(computeSystem, "Start", "", err, events)
	}
	logrus.Debugf(title + " succeeded")
	return nil
}
func (computeSystem *System) ID() string {
	return computeSystem.id
}
func (computeSystem *System) Shutdown() error {
	computeSystem.handleLock.RLock()
	defer computeSystem.handleLock.RUnlock()
	title := "hcsshim::ComputeSystem::Shutdown"
	logrus.Debugf(title)
	if computeSystem.handle == 0 {
		return makeSystemError(computeSystem, "Shutdown", "", ErrAlreadyClosed, nil)
	}
	var resultp *uint16
	err := hcsShutdownComputeSystem(computeSystem.handle, "", &resultp)
	events := processHcsResult(resultp)
	if err != nil {
		return makeSystemError(computeSystem, "Shutdown", "", err, events)
	}
	logrus.Debugf(title + " succeeded")
	return nil
}
func (computeSystem *System) Terminate() error {
	computeSystem.handleLock.RLock()
	defer computeSystem.handleLock.RUnlock()
	title := "hcsshim::ComputeSystem::Terminate ID=" + computeSystem.ID()
	logrus.Debugf(title)
	if computeSystem.handle == 0 {
		return makeSystemError(computeSystem, "Terminate", "", ErrAlreadyClosed, nil)
	}
	var resultp *uint16
	err := hcsTerminateComputeSystem(computeSystem.handle, "", &resultp)
	events := processHcsResult(resultp)
	if err != nil {
		return makeSystemError(computeSystem, "Terminate", "", err, events)
	}
	logrus.Debugf(title + " succeeded")
	return nil
}
func (computeSystem *System) Wait() error {
	title := "hcsshim::ComputeSystem::Wait ID=" + computeSystem.ID()
	logrus.Debugf(title)
	err := waitForNotification(computeSystem.callbackNumber, hcsNotificationSystemExited, nil)
	if err != nil {
		return makeSystemError(computeSystem, "Wait", "", err, nil)
	}
	logrus.Debugf(title + " succeeded")
	return nil
}