Skip to content
This repository was archived by the owner on Jan 30, 2025. It is now read-only.

Commit 202dd3a

Browse files
committed
Fix read/write race condition for edge case
This mutex is only needed in an edge case where we have multiple instances of k6 connecting to the same chrome instance. In this case when a page is created by the first k6 instance, the second instance of k6 will also receive an onAttachedToTarget event. When this occurs there's a small chance that at the same time a new context is being created by the second k6 instance. So the read occurs in getDefaultBrowserContextOrMatchedID which is called by onAttachedToTarget, and the write in NewContext. This mutex protects the read/write race condition for this one case.
1 parent e3cda41 commit 202dd3a

File tree

1 file changed

+16
-0
lines changed

1 file changed

+16
-0
lines changed

common/browser.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,16 @@ type Browser struct {
4747
// A *Connection is saved to this field, see: connect().
4848
conn connection
4949

50+
// This mutex is only needed in an edge case where we have multiple
51+
// instances of k6 connecting to the same chrome instance. In this
52+
// case when a page is created by the first k6 instance, the second
53+
// instance of k6 will also receive an onAttachedToTarget event. When
54+
// this occurs there's a small chance that at the same time a new
55+
// context is being created by the second k6 instance. So the read
56+
// occurs in getDefaultBrowserContextOrMatchedID which is called by
57+
// onAttachedToTarget, and the write in NewContext. This mutex protects
58+
// the read/write race condition for this one case.
59+
contextMu sync.RWMutex
5060
context *BrowserContext
5161
defaultContext *BrowserContext
5262

@@ -139,6 +149,9 @@ func (b *Browser) disposeContext(id cdp.BrowserContextID) error {
139149
// getDefaultBrowserContextOrMatchedID returns the BrowserContext for the given browser context ID.
140150
// If the browser context is not found, the default BrowserContext is returned.
141151
func (b *Browser) getDefaultBrowserContextOrMatchedID(id cdp.BrowserContextID) *BrowserContext {
152+
b.contextMu.RLock()
153+
defer b.contextMu.RUnlock()
154+
142155
if b.context == nil || b.context.id != id {
143156
return b.defaultContext
144157
}
@@ -512,6 +525,9 @@ func (b *Browser) NewContext(opts goja.Value) (api.BrowserContext, error) {
512525
if err != nil {
513526
return nil, fmt.Errorf("new context: %w", err)
514527
}
528+
529+
b.contextMu.Lock()
530+
defer b.contextMu.Unlock()
515531
b.context = browserCtx
516532

517533
return browserCtx, nil

0 commit comments

Comments
 (0)