浏览代码

#65 make placeholder thread safe

Tao Wen 8 年之前
父节点
当前提交
365d399192
共有 1 个文件被更改,包括 33 次插入9 次删除
  1. 33 9
      feature_reflect.go

+ 33 - 9
feature_reflect.go

@@ -6,6 +6,7 @@ import (
 	"fmt"
 	"reflect"
 	"unsafe"
+	"time"
 )
 
 // Decoder is an internal type registered to cache as needed.
@@ -169,11 +170,12 @@ func (encoder *optionalEncoder) isEmpty(ptr unsafe.Pointer) bool {
 }
 
 type placeholderEncoder struct {
-	valueEncoder Encoder
+	cfg *frozenConfig
+	cacheKey reflect.Type
 }
 
 func (encoder *placeholderEncoder) encode(ptr unsafe.Pointer, stream *Stream) {
-	encoder.valueEncoder.encode(ptr, stream)
+	encoder.getRealEncoder().encode(ptr, stream)
 }
 
 func (encoder *placeholderEncoder) encodeInterface(val interface{}, stream *Stream) {
@@ -181,15 +183,39 @@ func (encoder *placeholderEncoder) encodeInterface(val interface{}, stream *Stre
 }
 
 func (encoder *placeholderEncoder) isEmpty(ptr unsafe.Pointer) bool {
-	return encoder.valueEncoder.isEmpty(ptr)
+	return encoder.getRealEncoder().isEmpty(ptr)
+}
+
+func (encoder *placeholderEncoder) getRealEncoder() Encoder {
+	for i := 0; i < 30; i++ {
+		realDecoder := encoder.cfg.getEncoderFromCache(encoder.cacheKey)
+		_, isPlaceholder := realDecoder.(*placeholderEncoder)
+		if isPlaceholder {
+			time.Sleep(time.Second)
+		} else {
+			return realDecoder
+		}
+	}
+	panic(fmt.Sprintf("real encoder not found for cache key: %v", encoder.cacheKey))
 }
 
 type placeholderDecoder struct {
-	valueDecoder Decoder
+	cfg *frozenConfig
+	cacheKey reflect.Type
 }
 
 func (decoder *placeholderDecoder) decode(ptr unsafe.Pointer, iter *Iterator) {
-	decoder.valueDecoder.decode(ptr, iter)
+	for i := 0; i < 30; i++ {
+		realDecoder := decoder.cfg.getDecoderFromCache(decoder.cacheKey)
+		_, isPlaceholder := realDecoder.(*placeholderDecoder)
+		if isPlaceholder {
+			time.Sleep(time.Second)
+		} else {
+			realDecoder.decode(ptr, iter)
+			return
+		}
+	}
+	panic(fmt.Sprintf("real decoder not found for cache key: %v", decoder.cacheKey))
 }
 
 // emptyInterface is the header for an interface{} value.
@@ -283,10 +309,9 @@ func decoderOfType(cfg *frozenConfig, typ reflect.Type) (Decoder, error) {
 	if cachedDecoder != nil {
 		return cachedDecoder, nil
 	}
-	placeholder := &placeholderDecoder{}
+	placeholder := &placeholderDecoder{cfg: cfg, cacheKey: cacheKey}
 	cfg.addDecoderToCache(cacheKey, placeholder)
 	newDecoder, err := createDecoderOfType(cfg, typ)
-	placeholder.valueDecoder = newDecoder
 	cfg.addDecoderToCache(cacheKey, newDecoder)
 	return newDecoder, err
 }
@@ -382,10 +407,9 @@ func encoderOfType(cfg *frozenConfig, typ reflect.Type) (Encoder, error) {
 	if cachedEncoder != nil {
 		return cachedEncoder, nil
 	}
-	placeholder := &placeholderEncoder{}
+	placeholder := &placeholderEncoder{cfg: cfg, cacheKey: cacheKey}
 	cfg.addEncoderToCache(cacheKey, placeholder)
 	newEncoder, err := createEncoderOfType(cfg, typ)
-	placeholder.valueEncoder = newEncoder
 	cfg.addEncoderToCache(cacheKey, newEncoder)
 	return newEncoder, err
 }