-
-
Notifications
You must be signed in to change notification settings - Fork 17
/
Copy pathsyncer.go
47 lines (42 loc) · 1.36 KB
/
syncer.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
package handler
import (
"context"
"sync"
"github.com/sourcegraph/jsonrpc2"
)
// Synchronizer is used to block message processing while an edit or config change is applied.
type Synchronizer struct {
// FileMux is a read/write mutex for file access. It is locked during the processing of
// messages that modify target files for clangd.
FileMux sync.RWMutex
// DataMux is a mutex for document metadata access, i.e. source-target URI mappings and line mappings.
DataMux sync.RWMutex
}
// AsyncHandler wraps a Handler such that each request is handled in its own goroutine.
type AsyncHandler struct {
handler jsonrpc2.Handler
synchronizer *Synchronizer
}
// Handle handles a request or notification
func (ah AsyncHandler) Handle(ctx context.Context, conn *jsonrpc2.Conn, req *jsonrpc2.Request) {
needsWriteLock := req.Method == "textDocument/didOpen" || req.Method == "textDocument/didChange"
if needsWriteLock {
go func() {
ah.synchronizer.FileMux.Lock()
defer ah.synchronizer.FileMux.Unlock()
if enableLogging {
// log.Println("Message processing locked for", req.Method)
}
ah.handler.Handle(ctx, conn, req)
if enableLogging {
// log.Println("Message processing unlocked for", req.Method)
}
}()
} else {
go func() {
ah.synchronizer.FileMux.RLock()
ah.handler.Handle(ctx, conn, req)
ah.synchronizer.FileMux.RUnlock()
}()
}
}