@@ -14,13 +14,15 @@ import "C"
1414import (
1515 "errors"
1616 "log"
17+ "log/slog"
1718 "reflect"
1819 "runtime"
1920 "sync"
2021 "unsafe"
2122
2223 "github.com/diamondburned/gotk4/pkg/core/closure"
2324 "github.com/diamondburned/gotk4/pkg/core/gbox"
25+ "github.com/diamondburned/gotk4/pkg/core/gdebug"
2426 "github.com/diamondburned/gotk4/pkg/core/intern"
2527)
2628
@@ -451,32 +453,6 @@ func SourceRemove(src SourceHandle) bool {
451453 return gobool (C .g_source_remove (C .guint (src )))
452454}
453455
454- // WipeAllClosures wipes all the Go closures associated with the given object
455- // away. BE EXTREMELY CAREFUL WHEN USING THIS FUNCTION! If not careful, your
456- // program WILL crash!
457- //
458- // There is only one specific use case for this function: if your object has
459- // closures connected to it where these closures capture the object itself, then
460- // it might create a cyclic dependency on the GC, preventing its finalizer from
461- // ever running. This will cause the program to leak memory. As a temporary
462- // hack, this function is introduced for cases where the programmer knows for
463- // sure that the object will never be used again, and it is significant enough
464- // of a leak that having a workaround is better than not.
465- //
466- // Deprecated: this function is dangerous and should not be used. Using this
467- // function now causes a panic.
468- func WipeAllClosures (objector Objector ) {
469- panic ("WipeAllClosures is deprecated and should not be used" )
470- }
471-
472- // Destroy destroys the Go reference to the given object. The object must not be
473- // used ever again; it is the caller's responsibility to ensure that it will
474- // never be used again. Resurrecting the object again is undefined behavior.
475- func Destroy (objector Objector ) {
476- v := BaseObject (objector )
477- v .destroy ()
478- }
479-
480456// SignalHandle is the ID of a signal handler.
481457type SignalHandle uint
482458
@@ -505,6 +481,7 @@ func ConnectGeneratedClosure(
505481 userData := C .gpointer (gbox .Assign (data ))
506482
507483 gclosure := C .g_cclosure_new (C .GCallback (tramp ), userData , (* [0 ]byte )(C ._gotk4_removeGeneratedClosure ))
484+ // C.g_closure_add_invalidate_notifier(gclosure, userData, (*[0]byte)(C._gotk4_removeGeneratedClosure))
508485
509486 // Hold the GClosure reference.
510487 data .GClosure = uintptr (unsafe .Pointer (gclosure ))
@@ -531,29 +508,28 @@ func ConnectGeneratedClosure(
531508func ConnectedGeneratedClosure (closureData uintptr ) * closure.FuncStack {
532509 data , _ := gbox .Get (closureData ).(* generatedClosureData )
533510 if data == nil {
534- return nil
511+ slog .Error (
512+ "ConnectedGeneratedClosure: closure data not found in gbox" ,
513+ "data" , closureData )
514+ panic ("fatal error during callback" )
535515 }
536516
537517 // Get the function value associated with this callback closure.
538518 box := intern .TryGet (unsafe .Pointer (data .GObject ))
539519 if box == nil {
540- log .Printf (
541- "gotk4: warning: object %s %v cannot be resurrected" ,
542- typeFromObject (unsafe .Pointer (data .GObject )),
543- unsafe .Pointer (data .GObject ),
544- )
545- return nil
520+ slog .Error (
521+ "ConnectedGeneratedClosure: object cannot be resurrected for callback" ,
522+ gdebug .ObjectInfo (unsafe .Pointer (data .GObject )))
523+ panic ("fatal error during callback" )
546524 }
547525
548526 fs := box .Closures ().Load (unsafe .Pointer (data .GClosure ))
549527 if fs == nil {
550- log .Printf (
551- "gotk4: warning: object %s %v missing closure %v" ,
552- typeFromObject (unsafe .Pointer (data .GObject )),
553- unsafe .Pointer (data .GObject ),
554- unsafe .Pointer (data .GClosure ),
555- )
556- return nil
528+ slog .Error (
529+ "ConnectedGeneratedClosure: closure not found" ,
530+ "n_closures" , box .Closures ().Len (),
531+ gdebug .ObjectInfo (unsafe .Pointer (data .GObject )))
532+ panic ("fatal error during callback" )
557533 }
558534
559535 return fs
@@ -662,10 +638,6 @@ func newObject(ptr unsafe.Pointer, take bool) *Object {
662638 }
663639}
664640
665- func (v * Object ) destroy () {
666- intern .Free (v .box )
667- }
668-
669641// Cast casts v to the concrete Go type (e.g. *Object to *gtk.Entry).
670642//
671643//go:nosplit
@@ -1025,7 +997,7 @@ func marshalValue(p uintptr) (interface{}, error) {
1025997 }
1026998
1027999 v := & value {(* C .GValue )(unsafe .Pointer (c ))}
1028- runtime .SetFinalizer (v , ( * value ). unset )
1000+ runtime .AddCleanup (v , func ( v * C. GValue ) { C . g_value_unset ( v ) }, v . gvalue )
10291001
10301002 return & Value {v }, nil
10311003}
@@ -1058,7 +1030,7 @@ func AllocateValue() *Value {
10581030 //An allocated GValue is not guaranteed to hold a value that can be unset
10591031 //We need to double check before unsetting, to prevent:
10601032 //`g_value_unset: assertion 'G_IS_VALUE (value)' failed`
1061- runtime .SetFinalizer (v .value , ( * value ). unset )
1033+ runtime .AddCleanup (v .value , func ( v * C. GValue ) { C . g_value_unset ( v ) }, v . gvalue )
10621034
10631035 return v
10641036}
0 commit comments