func (s *RuntimeInitErrorState) ResponseSent() error {
	return ErrNotAllowed
}
InvocationErrorResponse not allowed
package core
import (
	"errors"
	"sync"
	"time"
	"go.amzn.com/lambda/core/statejson"
)
type Suspendable interface {
	SuspendUnsafe()
	Release()
	Lock()
	Unlock()
}
type ManagedThread struct {
	operatorCondition      *sync.Cond
	operatorConditionValue bool
}
func (s *ManagedThread) SuspendUnsafe() {
	for !s.operatorConditionValue {
		s.operatorCondition.Wait()
	}
	s.operatorConditionValue = false  
}
func (s *ManagedThread) Release() {
	s.operatorCondition.L.Lock()
	defer s.operatorCondition.L.Unlock()
	s.operatorConditionValue = true
	s.operatorCondition.Signal()
}
func (s *ManagedThread) Lock() {
	s.operatorCondition.L.Lock()
}
func (s *ManagedThread) Unlock() {
	s.operatorCondition.L.Unlock()
}
func NewManagedThread() *ManagedThread {
	return &ManagedThread{
		operatorCondition:      sync.NewCond(&sync.Mutex{}),
		operatorConditionValue: false,
	}
}
var ErrNotAllowed = errors.New("State transition is not allowed")
var ErrConcurrentStateModification = errors.New("Concurrent state modification")
type RuntimeState interface {
	InitError() error
	Ready() error
	InvocationResponse() error
	InvocationErrorResponse() error
	ResponseSent() error
	Name() string
}
type Runtime struct {
	ManagedThread Suspendable
	currentState      RuntimeState
	stateLastModified time.Time
	Pid               int
	responseTime      time.Time
	RuntimeStartedState                 RuntimeState
	RuntimeInitErrorState               RuntimeState
	RuntimeReadyState                   RuntimeState
	RuntimeInvocationResponseState      RuntimeState
	RuntimeInvocationErrorResponseState RuntimeState
	RuntimeResponseSentState            RuntimeState
}
func (s *Runtime) Release() {
	s.ManagedThread.Release()
}
func (s *Runtime) SetState(state RuntimeState) {
	s.ManagedThread.Lock()
	defer s.ManagedThread.Unlock()
	s.setStateUnsafe(state)
}
func (s *Runtime) setStateUnsafe(state RuntimeState) {
	s.currentState = state
	s.stateLastModified = time.Now()
}
func (s *Runtime) GetState() RuntimeState {
	s.ManagedThread.Lock()
	defer s.ManagedThread.Unlock()
	return s.currentState
}
func (s *Runtime) Ready() error {
	s.ManagedThread.Lock()
	defer s.ManagedThread.Unlock()
	return s.currentState.Ready()
}
func (s *Runtime) InvocationResponse() error {
	s.ManagedThread.Lock()
	defer s.ManagedThread.Unlock()
	return s.currentState.InvocationResponse()
}
func (s *Runtime) InvocationErrorResponse() error {
	s.ManagedThread.Lock()
	defer s.ManagedThread.Unlock()
	return s.currentState.InvocationErrorResponse()
}
func (s *Runtime) InitError() error {
	s.ManagedThread.Lock()
	defer s.ManagedThread.Unlock()
	return s.currentState.InitError()
}
func (s *Runtime) ResponseSent() error {
	s.ManagedThread.Lock()
	defer s.ManagedThread.Unlock()
	err := s.currentState.ResponseSent()
	if err == nil {
		s.responseTime = time.Now()
	}
	return err
}
func (s *Runtime) GetRuntimeDescription() statejson.RuntimeDescription {
	s.ManagedThread.Lock()
	defer s.ManagedThread.Unlock()
	res := statejson.RuntimeDescription{
		State: statejson.StateDescription{
			Name:         s.currentState.Name(),
			LastModified: s.stateLastModified.UnixNano() / int64(time.Millisecond),
		},
	}
	if !s.responseTime.IsZero() {
		res.State.ResponseTimeNs = s.responseTime.UnixNano()
	}
	return res
}
func NewRuntime(initFlow InitFlowSynchronization, invokeFlow InvokeFlowSynchronization) *Runtime {
	runtime := &Runtime{
		ManagedThread: NewManagedThread(),
	}
	runtime.RuntimeStartedState = &RuntimeStartedState{runtime: runtime, initFlow: initFlow}
	runtime.RuntimeInitErrorState = &RuntimeInitErrorState{runtime: runtime, initFlow: initFlow}
	runtime.RuntimeReadyState = &RuntimeReadyState{runtime: runtime, invokeFlow: invokeFlow}
	runtime.RuntimeInvocationResponseState = &RuntimeInvocationResponseState{runtime: runtime, invokeFlow: invokeFlow}
	runtime.RuntimeInvocationErrorResponseState = &RuntimeInvocationErrorResponseState{runtime: runtime, invokeFlow: invokeFlow}
	runtime.RuntimeResponseSentState = &RuntimeResponseSentState{runtime: runtime, invokeFlow: invokeFlow}
	runtime.setStateUnsafe(runtime.RuntimeStartedState)
	return runtime
}
type RuntimeStartedState struct {
	runtime  *Runtime
	initFlow InitFlowSynchronization
}
func (s *RuntimeStartedState) Ready() error {
	err := s.initFlow.RuntimeReady()
	if err != nil {
		return err
	}
	s.runtime.ManagedThread.SuspendUnsafe()
	s.runtime.setStateUnsafe(s.runtime.RuntimeReadyState)
	return nil
}
func (s *RuntimeStartedState) InvocationResponse() error {
	return ErrNotAllowed
}
func (s *RuntimeStartedState) InvocationErrorResponse() error {
	return ErrNotAllowed
}
func (s *RuntimeStartedState) ResponseSent() error {
	return ErrNotAllowed
}
func (s *RuntimeStartedState) InitError() error {
	s.runtime.setStateUnsafe(s.runtime.RuntimeInitErrorState)
	return nil
}
func (s *RuntimeStartedState) Name() string {
	return RuntimeStartedStateName
}
type RuntimeInitErrorState struct {
	runtime  *Runtime
	initFlow InitFlowSynchronization
}
func (s *RuntimeInitErrorState) Ready() error {
	return ErrNotAllowed
}
func (s *RuntimeInitErrorState) InvocationResponse() error {
	return ErrNotAllowed
}
func (s *RuntimeInitErrorState) InvocationErrorResponse() error {
	return ErrNotAllowed
}