|
10 | 10 | package internal |
11 | 11 |
|
12 | 12 | import ( |
13 | | - "encoding/binary" |
14 | 13 | "fmt" |
15 | 14 | "os" |
16 | 15 | "structs" |
17 | | - "sync/atomic" |
| 16 | + "sync" |
18 | 17 | "unsafe" |
19 | 18 |
|
20 | 19 | "golang.org/x/sys/unix" |
@@ -79,17 +78,22 @@ func CreateOtelProcessContextMapping(data []byte) error { |
79 | 78 | } |
80 | 79 |
|
81 | 80 | addr := uintptr(unsafe.Pointer(&mappingBytes[0])) |
82 | | - header := processContextHeader{ |
83 | | - Version: 1, |
84 | | - PayloadSize: uint32(len(data)), |
85 | | - PayloadAddr: addr + uintptr(headerSize), |
86 | | - } |
87 | 81 |
|
88 | | - copy(mappingBytes[headerSize:], data) |
89 | | - copy(mappingBytes[:headerSize], unsafe.Slice((*byte)(unsafe.Pointer(&header)), headerSize)) |
90 | | - // write atomically the signature last to ensure that once a process validates the signature, it can safely read the whole data |
91 | | - sig := binary.NativeEndian.Uint64(unsafe.Slice(unsafe.StringData(otelContextSignature), len(otelContextSignature))) |
92 | | - atomic.StoreUint64((*uint64)(unsafe.Pointer(&mappingBytes[0])), sig) |
| 82 | + var wg sync.WaitGroup |
| 83 | + wg.Add(1) |
| 84 | + go func() { |
| 85 | + defer wg.Done() |
| 86 | + header := processContextHeader{ |
| 87 | + Version: 1, |
| 88 | + PayloadSize: uint32(len(data)), |
| 89 | + PayloadAddr: addr + uintptr(headerSize), |
| 90 | + } |
| 91 | + copy(mappingBytes[headerSize:], data) |
| 92 | + copy(mappingBytes[:headerSize], unsafe.Slice((*byte)(unsafe.Pointer(&header)), headerSize)) |
| 93 | + }() |
| 94 | + wg.Wait() |
| 95 | + // write the signature last to ensure that once a process validates the signature, it can safely read the whole data |
| 96 | + copy(mappingBytes, otelContextSignature) |
93 | 97 |
|
94 | 98 | err = unix.Mprotect(mappingBytes, unix.PROT_READ) |
95 | 99 | if err != nil { |
|
0 commit comments