123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081 |
- 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)
- }
- // AddString adds a string to the pointer list by converting it to a C-char pointer and calling the AddPointer method.
- // The string is converted to a C-char pointer using the C.CString function.
- // It is recommended to use this method when you need to add a string to the pointer list.
- func (p *pointerList) AddString(str *C.char) {
- p.AddPointer(unsafe.Pointer(str))
- //getLogger().Warn("Adding string", zap.Int("i", len(p.Pointers)), zap.String("str", C.GoString(str)), zap.Stack("trace"))
- }
- // ToCString takes a string and converts it to a C string using C.CString. Then it calls the AddString method of
- // pointerList to add the resulting C string as a pointer to the pointer
- func (p *pointerList) ToCString(string string) *C.char {
- str := C.CString(string)
- p.AddString(str)
- return str
- }
- // FreeAll frees all C pointers
- func (p *pointerList) FreeAll() {
- for _, ptr := range p.Pointers {
- //getLogger().Warn("About to delete", zap.Int("i", i))
- 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),
- }
- }
|