Clarify Memory Ownership Model of libCwtch and Callers
continuous-integration/drone/pr Build is passing
Details
continuous-integration/drone/pr Build is passing
Details
Provides a way of telling libCwtch to free memory returned from functions that provide CStrings as results.
This commit is contained in:
parent
23c15130c7
commit
f86e670241
|
@ -0,0 +1,27 @@
|
|||
# Memory Model
|
||||
|
||||
This document provides an overview of the memory model of libCwtch. Callers should consult this document to ensure
|
||||
that they are properly handling pointers passed to-and-from libCwtch.
|
||||
|
||||
## Pointer Parameters
|
||||
|
||||
All pointers **passed** into functions in this library, except `c_FreePointer`, are assumed to be owned by the caller.
|
||||
|
||||
libCwtch **will not** modifying the underlying memory, nor attempt to free or otherwise modify these pointers.
|
||||
|
||||
This is realized by copying the underlying memory using `C.GoStringN`. libCwtch guarantees that it will not depend
|
||||
on the underlying memory of these pointers being available after returning from this function.
|
||||
|
||||
Callers are responsible for freeing these pointers after the call has been completed.
|
||||
|
||||
## Returned Pointers
|
||||
|
||||
All pointers **returned** by functions in libCwtch should be assumed to owned by libCwtch
|
||||
|
||||
Callers **must not** modifying the underlying memory of these pointers, nor attempt to free or otherwise modify these pointers
|
||||
through any method other than the one provided below.
|
||||
|
||||
Calling functions **must** copy the contents of the memory into their own memory space and then call `c_FreePointer` providing
|
||||
the returned pointer as a parameter.
|
||||
|
||||
libCwtch guarantees that it will not modify or free the underlying memory of these pointers prior to a call to `c_FreePointer`.
|
27
lib.go
27
lib.go
|
@ -2,7 +2,10 @@
|
|||
|
||||
package main
|
||||
|
||||
// //Needed to invoke C.free
|
||||
// #include <stdlib.h>
|
||||
import "C"
|
||||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"cwtch.im/cwtch/app"
|
||||
|
@ -21,6 +24,7 @@ import (
|
|||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
"unsafe"
|
||||
|
||||
"encoding/base64"
|
||||
"git.openprivacy.ca/openprivacy/connectivity/tor"
|
||||
|
@ -381,6 +385,7 @@ func SendProfileEvent(onion string, eventJson string) {
|
|||
}
|
||||
|
||||
//export c_GetAppBusEvent
|
||||
// the pointer returned from this function **must** be freed using c_Free
|
||||
func c_GetAppBusEvent() *C.char {
|
||||
return C.CString(GetAppBusEvent())
|
||||
}
|
||||
|
@ -427,20 +432,6 @@ func LoadProfiles(pass string) {
|
|||
application.LoadProfiles(pass)
|
||||
}
|
||||
|
||||
//export c_ContactEvents
|
||||
func c_ContactEvents() *C.char {
|
||||
return C.CString(ContactEvents())
|
||||
}
|
||||
|
||||
func ContactEvents() string {
|
||||
select {
|
||||
case myevent := <-contactEventsQueue.OutChan():
|
||||
return fmt.Sprintf("%v", myevent)
|
||||
default:
|
||||
return ""
|
||||
}
|
||||
}
|
||||
|
||||
//export c_AcceptContact
|
||||
func c_AcceptContact(profilePtr *C.char, profileLen C.int, handlePtr *C.char, handleLen C.int) {
|
||||
AcceptContact(C.GoStringN(profilePtr, profileLen), C.GoStringN(handlePtr, handleLen))
|
||||
|
@ -520,6 +511,7 @@ func UpdateMessageFlags(profileOnion, handle string, mIdx int, flags int64) {
|
|||
}
|
||||
|
||||
//export c_GetMessage
|
||||
// the pointer returned from this function **must** be Freed by c_Free
|
||||
func c_GetMessage(profile_ptr *C.char, profile_len C.int, handle_ptr *C.char, handle_len C.int, message_index C.int) *C.char {
|
||||
profile := C.GoStringN(profile_ptr, profile_len)
|
||||
handle := C.GoStringN(handle_ptr, handle_len)
|
||||
|
@ -585,6 +577,7 @@ func GetMessage(profileOnion, handle string, message_index int) string {
|
|||
}
|
||||
|
||||
//export c_GetMessagesByContentHash
|
||||
// the pointer returned from this function **must** be freed by calling c_Free
|
||||
func c_GetMessagesByContentHash(profile_ptr *C.char, profile_len C.int, handle_ptr *C.char, handle_len C.int, contenthash_ptr *C.char, contenthash_len C.int) *C.char {
|
||||
profile := C.GoStringN(profile_ptr, profile_len)
|
||||
handle := C.GoStringN(handle_ptr, handle_len)
|
||||
|
@ -592,6 +585,12 @@ func c_GetMessagesByContentHash(profile_ptr *C.char, profile_len C.int, handle_p
|
|||
return C.CString(GetMessagesByContentHash(profile, handle, contentHash))
|
||||
}
|
||||
|
||||
//export c_FreePointer
|
||||
// Dangerous function. Should only be used as documented in `MEMORY.md`
|
||||
func c_FreePointer(ptr *C.char) {
|
||||
C.free(unsafe.Pointer(ptr))
|
||||
}
|
||||
|
||||
func GetMessagesByContentHash(profileOnion, handle string, contentHash string) string {
|
||||
var indexedMessages []model.LocallyIndexedMessage
|
||||
if application != nil {
|
||||
|
|
Reference in New Issue