2021-07-20 17:59:04 +00:00
|
|
|
// +build windows
|
|
|
|
|
2019-09-27 21:51:53 +00:00
|
|
|
package etw
|
|
|
|
|
|
|
|
import (
|
|
|
|
"sync"
|
|
|
|
)
|
|
|
|
|
|
|
|
// Because the provider callback function needs to be able to access the
|
|
|
|
// provider data when it is invoked by ETW, we need to keep provider data stored
|
|
|
|
// in a global map based on an index. The index is passed as the callback
|
|
|
|
// context to ETW.
|
|
|
|
type providerMap struct {
|
|
|
|
m map[uint]*Provider
|
|
|
|
i uint
|
|
|
|
lock sync.Mutex
|
|
|
|
once sync.Once
|
|
|
|
}
|
|
|
|
|
|
|
|
var providers = providerMap{
|
|
|
|
m: make(map[uint]*Provider),
|
|
|
|
}
|
|
|
|
|
|
|
|
func (p *providerMap) newProvider() *Provider {
|
|
|
|
p.lock.Lock()
|
|
|
|
defer p.lock.Unlock()
|
|
|
|
|
|
|
|
i := p.i
|
|
|
|
p.i++
|
|
|
|
|
|
|
|
provider := &Provider{
|
|
|
|
index: i,
|
|
|
|
}
|
|
|
|
|
|
|
|
p.m[i] = provider
|
|
|
|
return provider
|
|
|
|
}
|
|
|
|
|
|
|
|
func (p *providerMap) removeProvider(provider *Provider) {
|
|
|
|
p.lock.Lock()
|
|
|
|
defer p.lock.Unlock()
|
|
|
|
|
|
|
|
delete(p.m, provider.index)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (p *providerMap) getProvider(index uint) *Provider {
|
|
|
|
p.lock.Lock()
|
|
|
|
defer p.lock.Unlock()
|
|
|
|
|
|
|
|
return p.m[index]
|
|
|
|
}
|
|
|
|
|
|
|
|
var providerCallbackOnce sync.Once
|
|
|
|
var globalProviderCallback uintptr
|