From: Michael Anthony Knyszek Date: Wed, 3 Dec 2025 23:07:26 +0000 (+0000) Subject: runtime: expand Pinner documentation X-Git-Tag: go1.26rc1~2^2~2 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=76345533f70e149511b1f50dbee598d0980cf867;p=gostls13.git runtime: expand Pinner documentation 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 Auto-Submit: Michael Knyszek Reviewed-by: Michael Pratt --- diff --git a/src/runtime/pinner.go b/src/runtime/pinner.go index dad14a4d09..fa0a8f5c53 100644 --- a/src/runtime/pinner.go +++ b/src/runtime/pinner.go @@ -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()