]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: expand Pinner documentation
authorMichael Anthony Knyszek <mknyszek@google.com>
Wed, 3 Dec 2025 23:07:26 +0000 (23:07 +0000)
committerGopher Robot <gobot@golang.org>
Fri, 5 Dec 2025 21:32:23 +0000 (13:32 -0800)
This change expands the Pinner documentation based on a few points of
feedback.
- We need a note that the Pinner has a finalizer.
- We need a note that the Pinner is safe to reuse.

I also added a note that the zero value is ready to use, and expanded
upon the use-cases of a Pinner.

Fixes #76431.

Change-Id: I312385557e67a815db05def02c1b1d7dcaa9d764
Reviewed-on: https://go-review.googlesource.com/c/go/+/726641
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Auto-Submit: Michael Knyszek <mknyszek@google.com>
Reviewed-by: Michael Pratt <mpratt@google.com>
src/runtime/pinner.go

index dad14a4d09c5e394c3953ba955bc64218cc813b9..fa0a8f5c53d7a3b6946cefd80357b0558c86b882 100644 (file)
@@ -12,7 +12,25 @@ import (
 
 // A Pinner is a set of Go objects each pinned to a fixed location in memory. The
 // [Pinner.Pin] method pins one object, while [Pinner.Unpin] unpins all pinned
-// objects. See their comments for more information.
+// objects.
+//
+// The purpose of a Pinner is two-fold.
+// First, it allows C code to safely use Go pointers that have not been passed
+// explicitly to the C code via a cgo call.
+// For example, for safely interacting with a pointer stored inside of a struct
+// whose pointer is passed to a C function.
+// Second, it allows C memory to safely retain that Go pointer even after the
+// cgo call returns, provided the object remains pinned.
+//
+// A Pinner arranges for its objects to be automatically unpinned some time after
+// it becomes unreachable, so its referents will not leak. However, this means the
+// Pinner itself must be kept alive across a cgo call, or as long as C retains a
+// reference to the pinned Go pointers.
+//
+// Reusing a Pinner is safe, and in fact encouraged, to avoid the cost of
+// initializing new Pinners on first use.
+//
+// The zero value of Pinner is ready to use.
 type Pinner struct {
        *pinner
 }
@@ -26,6 +44,7 @@ type Pinner struct {
 // are going to be accessed from C code.
 //
 // The argument must be a pointer of any type or an [unsafe.Pointer].
+//
 // It's safe to call Pin on non-Go pointers, in which case Pin will do nothing.
 func (p *Pinner) Pin(pointer any) {
        if p.pinner == nil {
@@ -63,6 +82,7 @@ func (p *Pinner) Pin(pointer any) {
 }
 
 // Unpin unpins all pinned objects of the [Pinner].
+// It's safe and encouraged to reuse a Pinner after calling Unpin.
 func (p *Pinner) Unpin() {
        p.pinner.unpin()