GoPLS Viewer

Home|gopls/internal/event/core/export.go
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.
4
5package core
6
7import (
8    "context"
9    "sync/atomic"
10    "time"
11    "unsafe"
12
13    "golang.org/x/tools/internal/event/label"
14)
15
16// Exporter is a function that handles events.
17// It may return a modified context and event.
18type Exporter func(context.ContextEventlabel.Mapcontext.Context
19
20var (
21    exporter unsafe.Pointer
22)
23
24// SetExporter sets the global exporter function that handles all events.
25// The exporter is called synchronously from the event call site, so it should
26// return quickly so as not to hold up user code.
27func SetExporter(e Exporter) {
28    p := unsafe.Pointer(&e)
29    if e == nil {
30        // &e is always valid, and so p is always valid, but for the early abort
31        // of ProcessEvent to be efficient it needs to make the nil check on the
32        // pointer without having to dereference it, so we make the nil function
33        // also a nil pointer
34        p = nil
35    }
36    atomic.StorePointer(&exporterp)
37}
38
39// deliver is called to deliver an event to the supplied exporter.
40// it will fill in the time.
41func deliver(ctx context.Contextexporter Exporterev Eventcontext.Context {
42    // add the current time to the event
43    ev.at = time.Now()
44    // hand the event off to the current exporter
45    return exporter(ctxevev)
46}
47
48// Export is called to deliver an event to the global exporter if set.
49func Export(ctx context.Contextev Eventcontext.Context {
50    // get the global exporter and abort early if there is not one
51    exporterPtr := (*Exporter)(atomic.LoadPointer(&exporter))
52    if exporterPtr == nil {
53        return ctx
54    }
55    return deliver(ctx, *exporterPtrev)
56}
57
58// ExportPair is called to deliver a start event to the supplied exporter.
59// It also returns a function that will deliver the end event to the same
60// exporter.
61// It will fill in the time.
62func ExportPair(ctx context.Contextbeginend Event) (context.Context, func()) {
63    // get the global exporter and abort early if there is not one
64    exporterPtr := (*Exporter)(atomic.LoadPointer(&exporter))
65    if exporterPtr == nil {
66        return ctx, func() {}
67    }
68    ctx = deliver(ctx, *exporterPtrbegin)
69    return ctx, func() { deliver(ctx, *exporterPtrend) }
70}
71
MembersX
context
unsafe
SetExporter
deliver.exporter
Export
ExportPair.ctx
Exporter
SetExporter.e
deliver.ctx
Export.ctx
Export.ev
ExportPair
ExportPair.begin
ExportPair.end
SetExporter.p
deliver
ExportPair.exporterPtr
atomic
exporter
deliver.ev
Export.exporterPtr
Members
X