Fixing race issues on nodes

This commit is contained in:
Kenneth Shaw 2017-02-18 14:28:43 +07:00
parent 2b0edf7c25
commit ab80f4c5bc
6 changed files with 217 additions and 150 deletions

View File

@ -10,5 +10,5 @@ before_install:
script: script:
- export CHROMEDP_NO_SANDBOX=true - export CHROMEDP_NO_SANDBOX=true
- export PATH=$PATH:$HOME/hs - export PATH=$PATH:$HOME/hs
- go test -v -coverprofile=coverage.out - go test -v -race -coverprofile=coverage.out
- goveralls -service=travis-ci -coverprofile=coverage.out - goveralls -service=travis-ci -coverprofile=coverage.out

View File

@ -1713,6 +1713,9 @@ func (n *Node) AttributeValue(name string) string {
// xpath builds the xpath string. // xpath builds the xpath string.
func (n *Node) xpath(stopAtDocument, stopAtID bool) string { func (n *Node) xpath(stopAtDocument, stopAtID bool) string {
n.RLock()
defer n.RUnlock()
p := "" p := ""
pos := "" pos := ""
id := n.AttributeValue("id") id := n.AttributeValue("id")
@ -1728,8 +1731,10 @@ func (n *Node) xpath(stopAtDocument, stopAtID bool) string {
pos = `[@id='` + id + `']` pos = `[@id='` + id + `']`
case n.Parent != nil: case n.Parent != nil:
i := 0 var i int
var found bool var found bool
n.Parent.RLock()
for j := 0; j < len(n.Parent.Children); j++ { for j := 0; j < len(n.Parent.Children); j++ {
if n.Parent.Children[j].LocalName == n.LocalName { if n.Parent.Children[j].LocalName == n.LocalName {
i++ i++
@ -1739,11 +1744,13 @@ func (n *Node) xpath(stopAtDocument, stopAtID bool) string {
break break
} }
} }
n.Parent.RUnlock()
p = n.Parent.xpath(stopAtDocument, stopAtID)
if found { if found {
pos = "[" + strconv.Itoa(i) + "]" pos = "[" + strconv.Itoa(i) + "]"
} }
p = n.Parent.xpath(stopAtDocument, stopAtID)
} }
return p + "/" + n.LocalName + pos return p + "/" + n.LocalName + pos

View File

@ -83,6 +83,9 @@ func (n *Node) AttributeValue(name string) string {
// xpath builds the xpath string. // xpath builds the xpath string.
func (n *Node) xpath(stopAtDocument, stopAtID bool) string { func (n *Node) xpath(stopAtDocument, stopAtID bool) string {
n.RLock()
defer n.RUnlock()
p := "" p := ""
pos := "" pos := ""
id := n.AttributeValue("id") id := n.AttributeValue("id")
@ -98,8 +101,10 @@ func (n *Node) xpath(stopAtDocument, stopAtID bool) string {
pos = `[@id='`+id+`']` pos = `[@id='`+id+`']`
case n.Parent != nil: case n.Parent != nil:
i := 0 var i int
var found bool var found bool
n.Parent.RLock()
for j := 0; j < len(n.Parent.Children); j++ { for j := 0; j < len(n.Parent.Children); j++ {
if n.Parent.Children[j].LocalName == n.LocalName { if n.Parent.Children[j].LocalName == n.LocalName {
i++ i++
@ -109,11 +114,13 @@ func (n *Node) xpath(stopAtDocument, stopAtID bool) string {
break break
} }
} }
n.Parent.RUnlock()
p = n.Parent.xpath(stopAtDocument, stopAtID)
if found { if found {
pos = "["+strconv.Itoa(i)+"]" pos = "["+strconv.Itoa(i)+"]"
} }
p = n.Parent.xpath(stopAtDocument, stopAtID)
} }
return p + "/" + n.LocalName + pos return p + "/" + n.LocalName + pos

View File

@ -192,6 +192,9 @@ func (n *Node) AttributeValue(name string) string {
// xpath builds the xpath string. // xpath builds the xpath string.
func (n *Node) xpath(stopAtDocument, stopAtID bool) string { func (n *Node) xpath(stopAtDocument, stopAtID bool) string {
n.RLock()
defer n.RUnlock()
p := "" p := ""
pos := "" pos := ""
id := n.AttributeValue("id") id := n.AttributeValue("id")
@ -223,8 +226,10 @@ func (n *Node) xpath(stopAtDocument, stopAtID bool) string {
qw422016.N().S(` qw422016.N().S(`
case n.Parent != nil: case n.Parent != nil:
i := 0 var i int
var found bool var found bool
n.Parent.RLock()
for j := 0; j < len(n.Parent.Children); j++ { for j := 0; j < len(n.Parent.Children); j++ {
if n.Parent.Children[j].LocalName == n.LocalName { if n.Parent.Children[j].LocalName == n.LocalName {
i++ i++
@ -234,11 +239,13 @@ func (n *Node) xpath(stopAtDocument, stopAtID bool) string {
break break
} }
} }
n.Parent.RUnlock()
p = n.Parent.xpath(stopAtDocument, stopAtID)
if found { if found {
pos = "["+strconv.Itoa(i)+"]" pos = "["+strconv.Itoa(i)+"]"
} }
p = n.Parent.xpath(stopAtDocument, stopAtID)
} }
return p + "/" + n.LocalName + pos return p + "/" + n.LocalName + pos
@ -296,136 +303,136 @@ func (ns NodeState) String() string {
return "[" + strings.Join(s, " ") + "]" return "[" + strings.Join(s, " ") + "]"
} }
`) `)
//line templates/extra.qtpl:173 //line templates/extra.qtpl:180
} }
//line templates/extra.qtpl:173 //line templates/extra.qtpl:180
func WriteExtraNodeTemplate(qq422016 qtio422016.Writer) { func WriteExtraNodeTemplate(qq422016 qtio422016.Writer) {
//line templates/extra.qtpl:173 //line templates/extra.qtpl:180
qw422016 := qt422016.AcquireWriter(qq422016) qw422016 := qt422016.AcquireWriter(qq422016)
//line templates/extra.qtpl:173 //line templates/extra.qtpl:180
StreamExtraNodeTemplate(qw422016) StreamExtraNodeTemplate(qw422016)
//line templates/extra.qtpl:173 //line templates/extra.qtpl:180
qt422016.ReleaseWriter(qw422016) qt422016.ReleaseWriter(qw422016)
//line templates/extra.qtpl:173 //line templates/extra.qtpl:180
} }
//line templates/extra.qtpl:173 //line templates/extra.qtpl:180
func ExtraNodeTemplate() string { func ExtraNodeTemplate() string {
//line templates/extra.qtpl:173 //line templates/extra.qtpl:180
qb422016 := qt422016.AcquireByteBuffer() qb422016 := qt422016.AcquireByteBuffer()
//line templates/extra.qtpl:173 //line templates/extra.qtpl:180
WriteExtraNodeTemplate(qb422016) WriteExtraNodeTemplate(qb422016)
//line templates/extra.qtpl:173 //line templates/extra.qtpl:180
qs422016 := string(qb422016.B) qs422016 := string(qb422016.B)
//line templates/extra.qtpl:173 //line templates/extra.qtpl:180
qt422016.ReleaseByteBuffer(qb422016) qt422016.ReleaseByteBuffer(qb422016)
//line templates/extra.qtpl:173 //line templates/extra.qtpl:180
return qs422016 return qs422016
//line templates/extra.qtpl:173 //line templates/extra.qtpl:180
} }
// ExtraFixStringUnmarshaler is a template that forces values to be parsed properly. // ExtraFixStringUnmarshaler is a template that forces values to be parsed properly.
//line templates/extra.qtpl:176 //line templates/extra.qtpl:183
func StreamExtraFixStringUnmarshaler(qw422016 *qt422016.Writer, typ, parseFunc, extra string) { func StreamExtraFixStringUnmarshaler(qw422016 *qt422016.Writer, typ, parseFunc, extra string) {
//line templates/extra.qtpl:176 //line templates/extra.qtpl:183
qw422016.N().S(` qw422016.N().S(`
// UnmarshalEasyJSON satisfies easyjson.Unmarshaler. // UnmarshalEasyJSON satisfies easyjson.Unmarshaler.
func (t *`) func (t *`)
//line templates/extra.qtpl:178 //line templates/extra.qtpl:185
qw422016.N().S(typ) qw422016.N().S(typ)
//line templates/extra.qtpl:178 //line templates/extra.qtpl:185
qw422016.N().S(`) UnmarshalEasyJSON(in *jlexer.Lexer) { qw422016.N().S(`) UnmarshalEasyJSON(in *jlexer.Lexer) {
buf := in.Raw() buf := in.Raw()
if l := len(buf); l > 2 && buf[0] == '"' && buf[l-1] == '"' { if l := len(buf); l > 2 && buf[0] == '"' && buf[l-1] == '"' {
buf = buf[1:l-1] buf = buf[1:l-1]
} }
`) `)
//line templates/extra.qtpl:183 //line templates/extra.qtpl:190
if parseFunc != "" { if parseFunc != "" {
//line templates/extra.qtpl:183 //line templates/extra.qtpl:190
qw422016.N().S(` qw422016.N().S(`
v, err := strconv.`) v, err := strconv.`)
//line templates/extra.qtpl:184 //line templates/extra.qtpl:191
qw422016.N().S(parseFunc) qw422016.N().S(parseFunc)
//line templates/extra.qtpl:184 //line templates/extra.qtpl:191
qw422016.N().S(`(string(buf)`) qw422016.N().S(`(string(buf)`)
//line templates/extra.qtpl:184 //line templates/extra.qtpl:191
qw422016.N().S(extra) qw422016.N().S(extra)
//line templates/extra.qtpl:184 //line templates/extra.qtpl:191
qw422016.N().S(`) qw422016.N().S(`)
if err != nil { if err != nil {
in.AddError(err) in.AddError(err)
} }
`) `)
//line templates/extra.qtpl:188 //line templates/extra.qtpl:195
} }
//line templates/extra.qtpl:188 //line templates/extra.qtpl:195
qw422016.N().S(` qw422016.N().S(`
*t = `) *t = `)
//line templates/extra.qtpl:189 //line templates/extra.qtpl:196
qw422016.N().S(typ) qw422016.N().S(typ)
//line templates/extra.qtpl:189 //line templates/extra.qtpl:196
qw422016.N().S(`(`) qw422016.N().S(`(`)
//line templates/extra.qtpl:189 //line templates/extra.qtpl:196
if parseFunc != "" { if parseFunc != "" {
//line templates/extra.qtpl:189 //line templates/extra.qtpl:196
qw422016.N().S(`v`) qw422016.N().S(`v`)
//line templates/extra.qtpl:189 //line templates/extra.qtpl:196
} else { } else {
//line templates/extra.qtpl:189 //line templates/extra.qtpl:196
qw422016.N().S(`buf`) qw422016.N().S(`buf`)
//line templates/extra.qtpl:189 //line templates/extra.qtpl:196
} }
//line templates/extra.qtpl:189 //line templates/extra.qtpl:196
qw422016.N().S(`) qw422016.N().S(`)
} }
// UnmarshalJSON satisfies json.Unmarshaler. // UnmarshalJSON satisfies json.Unmarshaler.
func (t *`) func (t *`)
//line templates/extra.qtpl:193 //line templates/extra.qtpl:200
qw422016.N().S(typ) qw422016.N().S(typ)
//line templates/extra.qtpl:193 //line templates/extra.qtpl:200
qw422016.N().S(`) UnmarshalJSON(buf []byte) error { qw422016.N().S(`) UnmarshalJSON(buf []byte) error {
return easyjson.Unmarshal(buf, t) return easyjson.Unmarshal(buf, t)
} }
`) `)
//line templates/extra.qtpl:196 //line templates/extra.qtpl:203
} }
//line templates/extra.qtpl:196 //line templates/extra.qtpl:203
func WriteExtraFixStringUnmarshaler(qq422016 qtio422016.Writer, typ, parseFunc, extra string) { func WriteExtraFixStringUnmarshaler(qq422016 qtio422016.Writer, typ, parseFunc, extra string) {
//line templates/extra.qtpl:196 //line templates/extra.qtpl:203
qw422016 := qt422016.AcquireWriter(qq422016) qw422016 := qt422016.AcquireWriter(qq422016)
//line templates/extra.qtpl:196 //line templates/extra.qtpl:203
StreamExtraFixStringUnmarshaler(qw422016, typ, parseFunc, extra) StreamExtraFixStringUnmarshaler(qw422016, typ, parseFunc, extra)
//line templates/extra.qtpl:196 //line templates/extra.qtpl:203
qt422016.ReleaseWriter(qw422016) qt422016.ReleaseWriter(qw422016)
//line templates/extra.qtpl:196 //line templates/extra.qtpl:203
} }
//line templates/extra.qtpl:196 //line templates/extra.qtpl:203
func ExtraFixStringUnmarshaler(typ, parseFunc, extra string) string { func ExtraFixStringUnmarshaler(typ, parseFunc, extra string) string {
//line templates/extra.qtpl:196 //line templates/extra.qtpl:203
qb422016 := qt422016.AcquireByteBuffer() qb422016 := qt422016.AcquireByteBuffer()
//line templates/extra.qtpl:196 //line templates/extra.qtpl:203
WriteExtraFixStringUnmarshaler(qb422016, typ, parseFunc, extra) WriteExtraFixStringUnmarshaler(qb422016, typ, parseFunc, extra)
//line templates/extra.qtpl:196 //line templates/extra.qtpl:203
qs422016 := string(qb422016.B) qs422016 := string(qb422016.B)
//line templates/extra.qtpl:196 //line templates/extra.qtpl:203
qt422016.ReleaseByteBuffer(qb422016) qt422016.ReleaseByteBuffer(qb422016)
//line templates/extra.qtpl:196 //line templates/extra.qtpl:203
return qs422016 return qs422016
//line templates/extra.qtpl:196 //line templates/extra.qtpl:203
} }
// ExtraExceptionDetailsTemplate is a special template for the Runtime.ExceptionDetails type that // ExtraExceptionDetailsTemplate is a special template for the Runtime.ExceptionDetails type that
// defines the standard error interface. // defines the standard error interface.
//line templates/extra.qtpl:200 //line templates/extra.qtpl:207
func StreamExtraExceptionDetailsTemplate(qw422016 *qt422016.Writer) { func StreamExtraExceptionDetailsTemplate(qw422016 *qt422016.Writer) {
//line templates/extra.qtpl:200 //line templates/extra.qtpl:207
qw422016.N().S(` qw422016.N().S(`
// Error satisfies the error interface. // Error satisfies the error interface.
func (e *ExceptionDetails) Error() string { func (e *ExceptionDetails) Error() string {
@ -434,41 +441,41 @@ func (e *ExceptionDetails) Error() string {
return fmt.Sprintf("encountered exception '%s' (%d:%d)", e.Text, e.LineNumber, e.ColumnNumber) return fmt.Sprintf("encountered exception '%s' (%d:%d)", e.Text, e.LineNumber, e.ColumnNumber)
} }
`) `)
//line templates/extra.qtpl:207 //line templates/extra.qtpl:214
} }
//line templates/extra.qtpl:207 //line templates/extra.qtpl:214
func WriteExtraExceptionDetailsTemplate(qq422016 qtio422016.Writer) { func WriteExtraExceptionDetailsTemplate(qq422016 qtio422016.Writer) {
//line templates/extra.qtpl:207 //line templates/extra.qtpl:214
qw422016 := qt422016.AcquireWriter(qq422016) qw422016 := qt422016.AcquireWriter(qq422016)
//line templates/extra.qtpl:207 //line templates/extra.qtpl:214
StreamExtraExceptionDetailsTemplate(qw422016) StreamExtraExceptionDetailsTemplate(qw422016)
//line templates/extra.qtpl:207 //line templates/extra.qtpl:214
qt422016.ReleaseWriter(qw422016) qt422016.ReleaseWriter(qw422016)
//line templates/extra.qtpl:207 //line templates/extra.qtpl:214
} }
//line templates/extra.qtpl:207 //line templates/extra.qtpl:214
func ExtraExceptionDetailsTemplate() string { func ExtraExceptionDetailsTemplate() string {
//line templates/extra.qtpl:207 //line templates/extra.qtpl:214
qb422016 := qt422016.AcquireByteBuffer() qb422016 := qt422016.AcquireByteBuffer()
//line templates/extra.qtpl:207 //line templates/extra.qtpl:214
WriteExtraExceptionDetailsTemplate(qb422016) WriteExtraExceptionDetailsTemplate(qb422016)
//line templates/extra.qtpl:207 //line templates/extra.qtpl:214
qs422016 := string(qb422016.B) qs422016 := string(qb422016.B)
//line templates/extra.qtpl:207 //line templates/extra.qtpl:214
qt422016.ReleaseByteBuffer(qb422016) qt422016.ReleaseByteBuffer(qb422016)
//line templates/extra.qtpl:207 //line templates/extra.qtpl:214
return qs422016 return qs422016
//line templates/extra.qtpl:207 //line templates/extra.qtpl:214
} }
// ExtraCDPTypes is the template for additional internal type // ExtraCDPTypes is the template for additional internal type
// declarations. // declarations.
//line templates/extra.qtpl:211 //line templates/extra.qtpl:218
func StreamExtraCDPTypes(qw422016 *qt422016.Writer) { func StreamExtraCDPTypes(qw422016 *qt422016.Writer) {
//line templates/extra.qtpl:211 //line templates/extra.qtpl:218
qw422016.N().S(` qw422016.N().S(`
// Error satisfies the error interface. // Error satisfies the error interface.
@ -502,40 +509,40 @@ type Handler interface {
Release(<-chan interface{}) Release(<-chan interface{})
} }
`) `)
//line templates/extra.qtpl:243 //line templates/extra.qtpl:250
} }
//line templates/extra.qtpl:243 //line templates/extra.qtpl:250
func WriteExtraCDPTypes(qq422016 qtio422016.Writer) { func WriteExtraCDPTypes(qq422016 qtio422016.Writer) {
//line templates/extra.qtpl:243 //line templates/extra.qtpl:250
qw422016 := qt422016.AcquireWriter(qq422016) qw422016 := qt422016.AcquireWriter(qq422016)
//line templates/extra.qtpl:243 //line templates/extra.qtpl:250
StreamExtraCDPTypes(qw422016) StreamExtraCDPTypes(qw422016)
//line templates/extra.qtpl:243 //line templates/extra.qtpl:250
qt422016.ReleaseWriter(qw422016) qt422016.ReleaseWriter(qw422016)
//line templates/extra.qtpl:243 //line templates/extra.qtpl:250
} }
//line templates/extra.qtpl:243 //line templates/extra.qtpl:250
func ExtraCDPTypes() string { func ExtraCDPTypes() string {
//line templates/extra.qtpl:243 //line templates/extra.qtpl:250
qb422016 := qt422016.AcquireByteBuffer() qb422016 := qt422016.AcquireByteBuffer()
//line templates/extra.qtpl:243 //line templates/extra.qtpl:250
WriteExtraCDPTypes(qb422016) WriteExtraCDPTypes(qb422016)
//line templates/extra.qtpl:243 //line templates/extra.qtpl:250
qs422016 := string(qb422016.B) qs422016 := string(qb422016.B)
//line templates/extra.qtpl:243 //line templates/extra.qtpl:250
qt422016.ReleaseByteBuffer(qb422016) qt422016.ReleaseByteBuffer(qb422016)
//line templates/extra.qtpl:243 //line templates/extra.qtpl:250
return qs422016 return qs422016
//line templates/extra.qtpl:243 //line templates/extra.qtpl:250
} }
// ExtraUtilTemplate generates the decode func for the Message type. // ExtraUtilTemplate generates the decode func for the Message type.
//line templates/extra.qtpl:246 //line templates/extra.qtpl:253
func StreamExtraUtilTemplate(qw422016 *qt422016.Writer, domains []*internal.Domain) { func StreamExtraUtilTemplate(qw422016 *qt422016.Writer, domains []*internal.Domain) {
//line templates/extra.qtpl:246 //line templates/extra.qtpl:253
qw422016.N().S(` qw422016.N().S(`
type empty struct{} type empty struct{}
var emptyVal = &empty{} var emptyVal = &empty{}
@ -544,66 +551,66 @@ var emptyVal = &empty{}
func UnmarshalMessage(msg *cdp.Message) (interface{}, error) { func UnmarshalMessage(msg *cdp.Message) (interface{}, error) {
var v easyjson.Unmarshaler var v easyjson.Unmarshaler
switch msg.Method {`) switch msg.Method {`)
//line templates/extra.qtpl:253 //line templates/extra.qtpl:260
for _, d := range domains { for _, d := range domains {
//line templates/extra.qtpl:253 //line templates/extra.qtpl:260
for _, c := range d.Commands { for _, c := range d.Commands {
//line templates/extra.qtpl:253 //line templates/extra.qtpl:260
qw422016.N().S(` qw422016.N().S(`
case cdp.`) case cdp.`)
//line templates/extra.qtpl:254 //line templates/extra.qtpl:261
qw422016.N().S(c.CommandMethodType(d)) qw422016.N().S(c.CommandMethodType(d))
//line templates/extra.qtpl:254 //line templates/extra.qtpl:261
qw422016.N().S(`:`) qw422016.N().S(`:`)
//line templates/extra.qtpl:254 //line templates/extra.qtpl:261
if len(c.Returns) == 0 { if len(c.Returns) == 0 {
//line templates/extra.qtpl:254 //line templates/extra.qtpl:261
qw422016.N().S(` qw422016.N().S(`
return emptyVal, nil`) return emptyVal, nil`)
//line templates/extra.qtpl:255 //line templates/extra.qtpl:262
} else { } else {
//line templates/extra.qtpl:255 //line templates/extra.qtpl:262
qw422016.N().S(` qw422016.N().S(`
v = new(`) v = new(`)
//line templates/extra.qtpl:256 //line templates/extra.qtpl:263
qw422016.N().S(d.PackageRefName()) qw422016.N().S(d.PackageRefName())
//line templates/extra.qtpl:256 //line templates/extra.qtpl:263
qw422016.N().S(`.`) qw422016.N().S(`.`)
//line templates/extra.qtpl:256 //line templates/extra.qtpl:263
qw422016.N().S(c.CommandReturnsType()) qw422016.N().S(c.CommandReturnsType())
//line templates/extra.qtpl:256 //line templates/extra.qtpl:263
qw422016.N().S(`)`) qw422016.N().S(`)`)
//line templates/extra.qtpl:256 //line templates/extra.qtpl:263
} }
//line templates/extra.qtpl:256 //line templates/extra.qtpl:263
qw422016.N().S(` qw422016.N().S(`
`) `)
//line templates/extra.qtpl:257 //line templates/extra.qtpl:264
} }
//line templates/extra.qtpl:257 //line templates/extra.qtpl:264
for _, e := range d.Events { for _, e := range d.Events {
//line templates/extra.qtpl:257 //line templates/extra.qtpl:264
qw422016.N().S(` qw422016.N().S(`
case cdp.`) case cdp.`)
//line templates/extra.qtpl:258 //line templates/extra.qtpl:265
qw422016.N().S(e.EventMethodType(d)) qw422016.N().S(e.EventMethodType(d))
//line templates/extra.qtpl:258 //line templates/extra.qtpl:265
qw422016.N().S(`: qw422016.N().S(`:
v = new(`) v = new(`)
//line templates/extra.qtpl:259 //line templates/extra.qtpl:266
qw422016.N().S(d.PackageRefName()) qw422016.N().S(d.PackageRefName())
//line templates/extra.qtpl:259 //line templates/extra.qtpl:266
qw422016.N().S(`.`) qw422016.N().S(`.`)
//line templates/extra.qtpl:259 //line templates/extra.qtpl:266
qw422016.N().S(e.EventType()) qw422016.N().S(e.EventType())
//line templates/extra.qtpl:259 //line templates/extra.qtpl:266
qw422016.N().S(`) qw422016.N().S(`)
`) `)
//line templates/extra.qtpl:260 //line templates/extra.qtpl:267
} }
//line templates/extra.qtpl:260 //line templates/extra.qtpl:267
} }
//line templates/extra.qtpl:260 //line templates/extra.qtpl:267
qw422016.N().S(`} qw422016.N().S(`}
var buf easyjson.RawMessage var buf easyjson.RawMessage
@ -626,69 +633,69 @@ func UnmarshalMessage(msg *cdp.Message) (interface{}, error) {
return v, nil return v, nil
} }
`) `)
//line templates/extra.qtpl:281 //line templates/extra.qtpl:288
} }
//line templates/extra.qtpl:281 //line templates/extra.qtpl:288
func WriteExtraUtilTemplate(qq422016 qtio422016.Writer, domains []*internal.Domain) { func WriteExtraUtilTemplate(qq422016 qtio422016.Writer, domains []*internal.Domain) {
//line templates/extra.qtpl:281 //line templates/extra.qtpl:288
qw422016 := qt422016.AcquireWriter(qq422016) qw422016 := qt422016.AcquireWriter(qq422016)
//line templates/extra.qtpl:281 //line templates/extra.qtpl:288
StreamExtraUtilTemplate(qw422016, domains) StreamExtraUtilTemplate(qw422016, domains)
//line templates/extra.qtpl:281 //line templates/extra.qtpl:288
qt422016.ReleaseWriter(qw422016) qt422016.ReleaseWriter(qw422016)
//line templates/extra.qtpl:281 //line templates/extra.qtpl:288
} }
//line templates/extra.qtpl:281 //line templates/extra.qtpl:288
func ExtraUtilTemplate(domains []*internal.Domain) string { func ExtraUtilTemplate(domains []*internal.Domain) string {
//line templates/extra.qtpl:281 //line templates/extra.qtpl:288
qb422016 := qt422016.AcquireByteBuffer() qb422016 := qt422016.AcquireByteBuffer()
//line templates/extra.qtpl:281 //line templates/extra.qtpl:288
WriteExtraUtilTemplate(qb422016, domains) WriteExtraUtilTemplate(qb422016, domains)
//line templates/extra.qtpl:281 //line templates/extra.qtpl:288
qs422016 := string(qb422016.B) qs422016 := string(qb422016.B)
//line templates/extra.qtpl:281 //line templates/extra.qtpl:288
qt422016.ReleaseByteBuffer(qb422016) qt422016.ReleaseByteBuffer(qb422016)
//line templates/extra.qtpl:281 //line templates/extra.qtpl:288
return qs422016 return qs422016
//line templates/extra.qtpl:281 //line templates/extra.qtpl:288
} }
//line templates/extra.qtpl:283 //line templates/extra.qtpl:290
func StreamExtraMethodTypeDomainDecoder(qw422016 *qt422016.Writer) { func StreamExtraMethodTypeDomainDecoder(qw422016 *qt422016.Writer) {
//line templates/extra.qtpl:283 //line templates/extra.qtpl:290
qw422016.N().S(` qw422016.N().S(`
// Domain returns the Chrome Debugging Protocol domain of the event or command. // Domain returns the Chrome Debugging Protocol domain of the event or command.
func (t MethodType) Domain() string { func (t MethodType) Domain() string {
return string(t[:strings.IndexByte(string(t), '.')]) return string(t[:strings.IndexByte(string(t), '.')])
} }
`) `)
//line templates/extra.qtpl:288 //line templates/extra.qtpl:295
} }
//line templates/extra.qtpl:288 //line templates/extra.qtpl:295
func WriteExtraMethodTypeDomainDecoder(qq422016 qtio422016.Writer) { func WriteExtraMethodTypeDomainDecoder(qq422016 qtio422016.Writer) {
//line templates/extra.qtpl:288 //line templates/extra.qtpl:295
qw422016 := qt422016.AcquireWriter(qq422016) qw422016 := qt422016.AcquireWriter(qq422016)
//line templates/extra.qtpl:288 //line templates/extra.qtpl:295
StreamExtraMethodTypeDomainDecoder(qw422016) StreamExtraMethodTypeDomainDecoder(qw422016)
//line templates/extra.qtpl:288 //line templates/extra.qtpl:295
qt422016.ReleaseWriter(qw422016) qt422016.ReleaseWriter(qw422016)
//line templates/extra.qtpl:288 //line templates/extra.qtpl:295
} }
//line templates/extra.qtpl:288 //line templates/extra.qtpl:295
func ExtraMethodTypeDomainDecoder() string { func ExtraMethodTypeDomainDecoder() string {
//line templates/extra.qtpl:288 //line templates/extra.qtpl:295
qb422016 := qt422016.AcquireByteBuffer() qb422016 := qt422016.AcquireByteBuffer()
//line templates/extra.qtpl:288 //line templates/extra.qtpl:295
WriteExtraMethodTypeDomainDecoder(qb422016) WriteExtraMethodTypeDomainDecoder(qb422016)
//line templates/extra.qtpl:288 //line templates/extra.qtpl:295
qs422016 := string(qb422016.B) qs422016 := string(qb422016.B)
//line templates/extra.qtpl:288 //line templates/extra.qtpl:295
qt422016.ReleaseByteBuffer(qb422016) qt422016.ReleaseByteBuffer(qb422016)
//line templates/extra.qtpl:288 //line templates/extra.qtpl:295
return qs422016 return qs422016
//line templates/extra.qtpl:288 //line templates/extra.qtpl:295
} }

View File

@ -664,9 +664,6 @@ func (h *TargetHandler) domEvent(ctxt context.Context, ev interface{}) {
f.Lock() f.Lock()
defer f.Unlock() defer f.Unlock()
n.Lock()
defer n.Unlock()
op(n) op(n)
} }

59
util.go
View File

@ -162,23 +162,34 @@ func clearFrameState(f *cdp.Frame, fs cdp.FrameState) {
type nodeOp func(*cdp.Node) type nodeOp func(*cdp.Node)
func walk(m map[cdp.NodeID]*cdp.Node, n *cdp.Node) { func walk(m map[cdp.NodeID]*cdp.Node, n *cdp.Node) {
n.RLock()
defer n.RUnlock()
m[n.NodeID] = n m[n.NodeID] = n
for _, c := range n.Children { for _, c := range n.Children {
c.Lock()
c.Parent = n c.Parent = n
c.Invalidated = n.Invalidated c.Invalidated = n.Invalidated
c.Unlock()
walk(m, c) walk(m, c)
} }
for _, c := range n.ShadowRoots { for _, c := range n.ShadowRoots {
c.Lock()
c.Parent = n c.Parent = n
c.Invalidated = n.Invalidated c.Invalidated = n.Invalidated
c.Unlock()
walk(m, c) walk(m, c)
} }
for _, c := range n.PseudoElements { for _, c := range n.PseudoElements {
c.Lock()
c.Parent = n c.Parent = n
c.Invalidated = n.Invalidated c.Invalidated = n.Invalidated
c.Unlock()
walk(m, c) walk(m, c)
} }
@ -187,24 +198,32 @@ func walk(m map[cdp.NodeID]*cdp.Node, n *cdp.Node) {
continue continue
} }
c.Lock()
c.Parent = n c.Parent = n
c.Invalidated = n.Invalidated c.Invalidated = n.Invalidated
c.Unlock()
walk(m, c) walk(m, c)
} }
} }
func setChildNodes(m map[cdp.NodeID]*cdp.Node, nodes []*cdp.Node) nodeOp { func setChildNodes(m map[cdp.NodeID]*cdp.Node, nodes []*cdp.Node) nodeOp {
return func(n *cdp.Node) { return func(n *cdp.Node) {
n.Lock()
n.Children = nodes n.Children = nodes
n.Unlock()
walk(m, n) walk(m, n)
} }
} }
func attributeModified(name, value string) nodeOp { func attributeModified(name, value string) nodeOp {
return func(n *cdp.Node) { return func(n *cdp.Node) {
var found bool n.Lock()
defer n.Unlock()
i := 0 var found bool
var i int
for ; i < len(n.Attributes); i += 2 { for ; i < len(n.Attributes); i += 2 {
if n.Attributes[i] == name { if n.Attributes[i] == name {
found = true found = true
@ -223,6 +242,9 @@ func attributeModified(name, value string) nodeOp {
func attributeRemoved(name string) nodeOp { func attributeRemoved(name string) nodeOp {
return func(n *cdp.Node) { return func(n *cdp.Node) {
n.Lock()
defer n.Unlock()
var a []string var a []string
for i := 0; i < len(n.Attributes); i += 2 { for i := 0; i < len(n.Attributes); i += 2 {
if n.Attributes[i] == name { if n.Attributes[i] == name {
@ -241,60 +263,87 @@ func inlineStyleInvalidated(ids []cdp.NodeID) nodeOp {
func characterDataModified(characterData string) nodeOp { func characterDataModified(characterData string) nodeOp {
return func(n *cdp.Node) { return func(n *cdp.Node) {
n.Lock()
defer n.Unlock()
n.Value = characterData n.Value = characterData
} }
} }
func childNodeCountUpdated(count int64) nodeOp { func childNodeCountUpdated(count int64) nodeOp {
return func(n *cdp.Node) { return func(n *cdp.Node) {
n.Lock()
defer n.Unlock()
n.ChildNodeCount = count n.ChildNodeCount = count
} }
} }
func childNodeInserted(m map[cdp.NodeID]*cdp.Node, prevID cdp.NodeID, c *cdp.Node) nodeOp { func childNodeInserted(m map[cdp.NodeID]*cdp.Node, prevID cdp.NodeID, c *cdp.Node) nodeOp {
return func(n *cdp.Node) { return func(n *cdp.Node) {
n.Lock()
n.Children = insertNode(n.Children, prevID, c) n.Children = insertNode(n.Children, prevID, c)
n.Unlock()
walk(m, n) walk(m, n)
} }
} }
func childNodeRemoved(m map[cdp.NodeID]*cdp.Node, id cdp.NodeID) nodeOp { func childNodeRemoved(m map[cdp.NodeID]*cdp.Node, id cdp.NodeID) nodeOp {
return func(n *cdp.Node) { return func(n *cdp.Node) {
n.Lock()
defer n.Unlock()
n.Children = removeNode(n.Children, id) n.Children = removeNode(n.Children, id)
//delete(m, id) delete(m, id)
} }
} }
func shadowRootPushed(m map[cdp.NodeID]*cdp.Node, c *cdp.Node) nodeOp { func shadowRootPushed(m map[cdp.NodeID]*cdp.Node, c *cdp.Node) nodeOp {
return func(n *cdp.Node) { return func(n *cdp.Node) {
n.Lock()
n.ShadowRoots = append(n.ShadowRoots, c) n.ShadowRoots = append(n.ShadowRoots, c)
n.Unlock()
walk(m, n) walk(m, n)
} }
} }
func shadowRootPopped(m map[cdp.NodeID]*cdp.Node, id cdp.NodeID) nodeOp { func shadowRootPopped(m map[cdp.NodeID]*cdp.Node, id cdp.NodeID) nodeOp {
return func(n *cdp.Node) { return func(n *cdp.Node) {
n.Lock()
defer n.Unlock()
n.ShadowRoots = removeNode(n.ShadowRoots, id) n.ShadowRoots = removeNode(n.ShadowRoots, id)
//delete(m, id) delete(m, id)
} }
} }
func pseudoElementAdded(m map[cdp.NodeID]*cdp.Node, c *cdp.Node) nodeOp { func pseudoElementAdded(m map[cdp.NodeID]*cdp.Node, c *cdp.Node) nodeOp {
return func(n *cdp.Node) { return func(n *cdp.Node) {
n.Lock()
n.PseudoElements = append(n.PseudoElements, c) n.PseudoElements = append(n.PseudoElements, c)
n.Unlock()
walk(m, n) walk(m, n)
} }
} }
func pseudoElementRemoved(m map[cdp.NodeID]*cdp.Node, id cdp.NodeID) nodeOp { func pseudoElementRemoved(m map[cdp.NodeID]*cdp.Node, id cdp.NodeID) nodeOp {
return func(n *cdp.Node) { return func(n *cdp.Node) {
n.Lock()
defer n.Unlock()
n.PseudoElements = removeNode(n.PseudoElements, id) n.PseudoElements = removeNode(n.PseudoElements, id)
//delete(m, id) delete(m, id)
} }
} }
func distributedNodesUpdated(nodes []*cdp.BackendNode) nodeOp { func distributedNodesUpdated(nodes []*cdp.BackendNode) nodeOp {
return func(n *cdp.Node) { return func(n *cdp.Node) {
n.Lock()
defer n.Unlock()
n.DistributedNodes = nodes n.DistributedNodes = nodes
} }
} }