@@ -36,6 +36,7 @@ import (
36
36
"strconv"
37
37
"strings"
38
38
"sync"
39
+ "sync/atomic"
39
40
"time"
40
41
41
42
"go.uber.org/cadence/internal/common/isolationgroup"
@@ -792,7 +793,7 @@ func (aw *aggregatedWorker) RegisterActivityWithOptions(a interface{}, options R
792
793
}
793
794
794
795
func (aw * aggregatedWorker ) Start () error {
795
- if err := initBinaryChecksum (); err != nil {
796
+ if _ , err := initBinaryChecksum (); err != nil {
796
797
return fmt .Errorf ("failed to get executable checksum: %v" , err )
797
798
}
798
799
@@ -874,66 +875,62 @@ func (aw *aggregatedWorker) Start() error {
874
875
return nil
875
876
}
876
877
877
- var binaryChecksum string
878
+ var binaryChecksum atomic. Value
878
879
var binaryChecksumLock sync.Mutex
879
880
880
881
// SetBinaryChecksum set binary checksum
881
882
func SetBinaryChecksum (checksum string ) {
882
- binaryChecksumLock .Lock ()
883
- defer binaryChecksumLock .Unlock ()
884
-
885
- binaryChecksum = checksum
883
+ binaryChecksum .Store (checksum )
886
884
}
887
885
888
- func initBinaryChecksum () error {
886
+ func initBinaryChecksum () (string , error ) {
887
+ // initBinaryChecksum may be called multiple times concurrently during worker startup.
888
+ // To avoid reading and hashing the contents of the binary multiple times acquire mutex here.
889
889
binaryChecksumLock .Lock ()
890
890
defer binaryChecksumLock .Unlock ()
891
891
892
- return initBinaryChecksumLocked ()
893
- }
894
-
895
- // callers MUST hold binaryChecksumLock before calling
896
- func initBinaryChecksumLocked () error {
897
- if len (binaryChecksum ) > 0 {
898
- return nil
892
+ // check if binaryChecksum already set/initialized.
893
+ if bcsVal , ok := binaryChecksum .Load ().(string ); ok {
894
+ return bcsVal , nil
899
895
}
900
896
901
897
exec , err := os .Executable ()
902
898
if err != nil {
903
- return err
899
+ return "" , err
904
900
}
905
901
906
902
f , err := os .Open (exec )
907
903
if err != nil {
908
- return err
904
+ return "" , err
909
905
}
910
906
defer func () {
911
907
_ = f .Close () // error is unimportant as it is read-only
912
908
}()
913
909
914
910
h := md5 .New ()
915
911
if _ , err := io .Copy (h , f ); err != nil {
916
- return err
912
+ return "" , err
917
913
}
918
914
919
915
checksum := h .Sum (nil )
920
- binaryChecksum = hex .EncodeToString (checksum [:])
916
+ bcsVal := hex .EncodeToString (checksum [:])
917
+ binaryChecksum .Store (bcsVal )
921
918
922
- return nil
919
+ return bcsVal , err
923
920
}
924
921
925
922
func getBinaryChecksum () string {
926
- binaryChecksumLock .Lock ()
927
- defer binaryChecksumLock .Unlock ()
923
+ bcsVal , ok := binaryChecksum .Load ().(string )
924
+ if ok {
925
+ return bcsVal
926
+ }
928
927
929
- if len (binaryChecksum ) == 0 {
930
- err := initBinaryChecksumLocked ()
931
- if err != nil {
932
- panic (err )
933
- }
928
+ bcsVal , err := initBinaryChecksum ()
929
+ if err != nil {
930
+ panic (err )
934
931
}
935
932
936
- return binaryChecksum
933
+ return bcsVal
937
934
}
938
935
939
936
func (aw * aggregatedWorker ) Run () error {
0 commit comments