@@ -25,10 +25,8 @@ type Pinner struct {
25
25
// objects, these objects must be pinned separately if they are going to be
26
26
// accessed from C code.
27
27
//
28
- // The argument must be a pointer of any type or an
29
- // unsafe.Pointer. It must be the result of calling new,
30
- // taking the address of a composite literal, or taking the address of a
31
- // local variable. If one of these conditions is not met, Pin will panic.
28
+ // The argument must be a pointer of any type or an unsafe.Pointer.
29
+ // It's safe to call Pin on non-Go pointers, in which case Pin will do nothing.
32
30
func (p * Pinner ) Pin (pointer any ) {
33
31
if p .pinner == nil {
34
32
// Check the pinner cache first.
@@ -59,8 +57,9 @@ func (p *Pinner) Pin(pointer any) {
59
57
}
60
58
}
61
59
ptr := pinnerGetPtr (& pointer )
62
- setPinned (ptr , true )
63
- p .refs = append (p .refs , ptr )
60
+ if setPinned (ptr , true ) {
61
+ p .refs = append (p .refs , ptr )
62
+ }
64
63
}
65
64
66
65
// Unpin unpins all pinned objects of the Pinner.
@@ -143,15 +142,19 @@ func isPinned(ptr unsafe.Pointer) bool {
143
142
return pinState .isPinned ()
144
143
}
145
144
146
- // setPinned marks or unmarks a Go pointer as pinned.
147
- func setPinned (ptr unsafe.Pointer , pin bool ) {
145
+ // setPinned marks or unmarks a Go pointer as pinned, when the ptr is a Go pointer.
146
+ // It will be ignored while try to pin a non-Go pointer,
147
+ // and it will be panic while try to unpin a non-Go pointer,
148
+ // which should not happen in normal usage.
149
+ func setPinned (ptr unsafe.Pointer , pin bool ) bool {
148
150
span := spanOfHeap (uintptr (ptr ))
149
151
if span == nil {
150
- if isGoPointerWithoutSpan (ptr ) {
151
- // this is a linker-allocated or zero size object, nothing to do.
152
- return
152
+ if ! pin {
153
+ panic (errorString ("tried to unpin non-Go pointer" ))
153
154
}
154
- panic (errorString ("runtime.Pinner.Pin: argument is not a Go pointer" ))
155
+ // This is a linker-allocated, zero size object or other object,
156
+ // nothing to do, silently ignore it.
157
+ return false
155
158
}
156
159
157
160
// ensure that the span is swept, b/c sweeping accesses the specials list
@@ -209,7 +212,7 @@ func setPinned(ptr unsafe.Pointer, pin bool) {
209
212
}
210
213
unlock (& span .speciallock )
211
214
releasem (mp )
212
- return
215
+ return true
213
216
}
214
217
215
218
type pinState struct {
0 commit comments