ソースを参照

Use sync/atomic for the interrupt flag (fixes #16, closes #18).

Dmitry Panov 8 年 前
コミット
9e6f360b03
1 ファイル変更10 行追加5 行削除
  1. 10 5
      vm.go

+ 10 - 5
vm.go

@@ -6,6 +6,7 @@ import (
 	"math"
 	"strconv"
 	"sync"
+	"sync/atomic"
 )
 
 const (
@@ -111,7 +112,7 @@ type vm struct {
 	stashAllocs int
 	halt        bool
 
-	interrupt     bool
+	interrupted   uint32
 	interruptVal  interface{}
 	interruptLock sync.Mutex
 }
@@ -277,16 +278,20 @@ func (vm *vm) init() {
 
 func (vm *vm) run() {
 	vm.halt = false
-	for !vm.halt && !vm.interrupt {
+	interrupted := false
+	for !vm.halt {
+		if interrupted = atomic.LoadUint32(&vm.interrupted) != 0; interrupted {
+			break
+		}
 		vm.prg.code[vm.pc].exec(vm)
 	}
 
-	if vm.interrupt {
+	if interrupted {
 		vm.interruptLock.Lock()
 		v := &InterruptedError{
 			iface: vm.interruptVal,
 		}
-		vm.interrupt = false
+		atomic.StoreUint32(&vm.interrupted, 0)
 		vm.interruptVal = nil
 		vm.interruptLock.Unlock()
 		panic(v)
@@ -296,7 +301,7 @@ func (vm *vm) run() {
 func (vm *vm) Interrupt(v interface{}) {
 	vm.interruptLock.Lock()
 	vm.interruptVal = v
-	vm.interrupt = true
+	atomic.StoreUint32(&vm.interrupted, 1)
 	vm.interruptLock.Unlock()
 }