github.com/Serizao/go-winio@v0.0.0-20230906082528-f02f7f4ad6e8/pkg/etw/providerglobal.go (about) 1 //go:build windows 2 // +build windows 3 4 package etw 5 6 import ( 7 "sync" 8 ) 9 10 // Because the provider callback function needs to be able to access the 11 // provider data when it is invoked by ETW, we need to keep provider data stored 12 // in a global map based on an index. The index is passed as the callback 13 // context to ETW. 14 type providerMap struct { 15 m map[uint]*Provider 16 i uint 17 lock sync.Mutex 18 } 19 20 var providers = providerMap{ 21 m: make(map[uint]*Provider), 22 } 23 24 func (p *providerMap) newProvider() *Provider { 25 p.lock.Lock() 26 defer p.lock.Unlock() 27 28 i := p.i 29 p.i++ 30 31 provider := &Provider{ 32 index: i, 33 } 34 35 p.m[i] = provider 36 return provider 37 } 38 39 func (p *providerMap) removeProvider(provider *Provider) { 40 p.lock.Lock() 41 defer p.lock.Unlock() 42 43 delete(p.m, provider.index) 44 } 45 46 func (p *providerMap) getProvider(index uint) *Provider { 47 p.lock.Lock() 48 defer p.lock.Unlock() 49 50 return p.m[index] 51 } 52 53 //todo: combine these into struct, so that "globalProviderCallback" is guaranteed to be initialized through method access 54 55 var providerCallbackOnce sync.Once 56 var globalProviderCallback uintptr