1 // Copyright 2019 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
13 "mvdan.cc/gofumpt/gofumports/internal/event/label"
16 // Exporter is a function that handles events.
17 // It may return a modified context and event.
18 type Exporter func(context.Context, Event, label.Map) context.Context
20 var exporter unsafe.Pointer
22 // SetExporter sets the global exporter function that handles all events.
23 // The exporter is called synchronously from the event call site, so it should
24 // return quickly so as not to hold up user code.
25 func SetExporter(e Exporter) {
26 p := unsafe.Pointer(&e)
28 // &e is always valid, and so p is always valid, but for the early abort
29 // of ProcessEvent to be efficient it needs to make the nil check on the
30 // pointer without having to dereference it, so we make the nil function
34 atomic.StorePointer(&exporter, p)
37 // deliver is called to deliver an event to the supplied exporter.
38 // it will fill in the time.
39 func deliver(ctx context.Context, exporter Exporter, ev Event) context.Context {
40 // add the current time to the event
42 // hand the event off to the current exporter
43 return exporter(ctx, ev, ev)
46 // Export is called to deliver an event to the global exporter if set.
47 func Export(ctx context.Context, ev Event) context.Context {
48 // get the global exporter and abort early if there is not one
49 exporterPtr := (*Exporter)(atomic.LoadPointer(&exporter))
50 if exporterPtr == nil {
53 return deliver(ctx, *exporterPtr, ev)
56 // ExportPair is called to deliver a start event to the supplied exporter.
57 // It also returns a function that will deliver the end event to the same
59 // It will fill in the time.
60 func ExportPair(ctx context.Context, begin, end Event) (context.Context, func()) {
61 // get the global exporter and abort early if there is not one
62 exporterPtr := (*Exporter)(atomic.LoadPointer(&exporter))
63 if exporterPtr == nil {
66 ctx = deliver(ctx, *exporterPtr, begin)
67 return ctx, func() { deliver(ctx, *exporterPtr, end) }