-
Notifications
You must be signed in to change notification settings - Fork 0
/
executor.go
123 lines (109 loc) · 3.84 KB
/
executor.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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
// Copyright (C) 2017 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package replay
import (
"context"
"github.com/google/gapid/core/app/status"
"github.com/google/gapid/core/data/id"
"github.com/google/gapid/core/log"
"github.com/google/gapid/core/os/device"
"github.com/google/gapid/gapir"
gapirClient "github.com/google/gapid/gapir/client"
"github.com/google/gapid/gapis/database"
"github.com/google/gapid/gapis/replay/builder"
)
type executor struct {
payload gapir.Payload
payloadID id.ID
dependent string
handlePost builder.PostDataHandler
handleNotification builder.NotificationHandler
fenceReadyCallback builder.FenceReadyRequestCallback
memoryLayout *device.MemoryLayout
OS *device.OS
finished chan error
}
// Execute sends the replay payload for execution on the target replay device
// communicating on connection.
// decoder will be used for decoding all postback reponses. Once a postback
// response is decoded, the corresponding handler in the handlers map will be
// called.
func Execute(
ctx context.Context,
dependent string,
payload gapir.Payload,
handlePost builder.PostDataHandler,
handleNotification builder.NotificationHandler,
fenceReadyCallback builder.FenceReadyRequestCallback,
m Manager,
conn *gapirClient.ConnectionKey,
memoryLayout *device.MemoryLayout,
os *device.OS) error {
ctx = status.Start(ctx, "Execute")
defer status.Finish(ctx)
// The memoryLayout is specific to the ABI of the requested capture,
// while the OS is not. Thus a device.Configuration is not applicable here.
return executor{
payload: payload,
dependent: dependent,
handlePost: handlePost,
handleNotification: handleNotification,
fenceReadyCallback: fenceReadyCallback,
memoryLayout: memoryLayout,
OS: os,
finished: make(chan error),
}.execute(ctx, m.(*manager), conn)
}
func (e executor) execute(ctx context.Context, m *manager, conn *gapirClient.ConnectionKey) error {
plid, err := database.Store(ctx, &e.payload)
if err != nil {
return log.Errf(ctx, err, "Storing replay payload")
}
e.payloadID = plid
log.I(ctx, "Replaying %v", plid)
clean, err := m.SetReplayExecutor(ctx, conn, e)
if err != nil {
return err
}
defer clean()
log.I(ctx, "Beginning replay %v", plid)
// Start replay with id
m.BeginReplay(ctx, conn, plid.String(), e.dependent)
// Wait for finished
err = <-e.finished
return err
}
func (e executor) HandleFinished(ctx context.Context, err error) error {
log.I(ctx, "Finished replay %v", e.payloadID)
e.finished <- err
return nil
}
// HandlePostData implements gapir.ReplayResponseHandler interface.
func (e executor) HandlePostData(ctx context.Context, postData *gapir.PostData) error {
ctx = status.Start(ctx, "Post Data (count: %d)", len(postData.PostDataPieces))
defer status.Finish(ctx)
e.handlePost(postData)
return nil
}
// HandleNotification implements gapir.ReplayResponseHandler interface.
func (e executor) HandleNotification(ctx context.Context, notification *gapir.Notification) error {
e.handleNotification(notification)
return nil
}
func (e executor) HandleFenceReadyRequest(ctx context.Context, req *gapir.FenceReadyRequest) error {
ctx = status.Start(ctx, "Fence Ready Request")
defer status.Finish(ctx)
e.fenceReadyCallback(req)
return nil
}