forked from dunglas/frankenphp
-
Notifications
You must be signed in to change notification settings - Fork 0
/
smartpointer.go
64 lines (54 loc) · 1.45 KB
/
smartpointer.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
package frankenphp
// #include <stdlib.h>
import "C"
import (
"runtime/cgo"
"unsafe"
)
/*
FrankenPHP is fairly complex because it shuffles handles/requests/contexts
between C and Go. This simplifies the lifecycle management of per-request
structures by allowing us to hold references until the end of the request
and ensure they are always cleaned up.
*/
// PointerList A list of pointers that can be freed at a later time
type pointerList struct {
Pointers []unsafe.Pointer
}
// HandleList A list of pointers that can be freed at a later time
type handleList struct {
Handles []cgo.Handle
}
// AddHandle Call when registering a handle for the very first time
func (h *handleList) AddHandle(handle cgo.Handle) {
h.Handles = append(h.Handles, handle)
}
// AddPointer Call when creating a request-level C pointer for the very first time
func (p *pointerList) AddPointer(ptr unsafe.Pointer) {
p.Pointers = append(p.Pointers, ptr)
}
// FreeAll frees all C pointers
func (p *pointerList) FreeAll() {
for _, ptr := range p.Pointers {
C.free(ptr)
}
p.Pointers = nil // To avoid dangling pointers
}
// FreeAll frees all handles
func (h *handleList) FreeAll() {
for _, p := range h.Handles {
p.Delete()
}
}
// Pointers Get a new list of pointers
func Pointers() *pointerList {
return &pointerList{
Pointers: make([]unsafe.Pointer, 0),
}
}
// Handles Get a new list of handles
func Handles() *handleList {
return &handleList{
Handles: make([]cgo.Handle, 0, 8),
}
}