@@ -14,13 +14,15 @@ import "C"
14
14
import (
15
15
"errors"
16
16
"log"
17
+ "log/slog"
17
18
"reflect"
18
19
"runtime"
19
20
"sync"
20
21
"unsafe"
21
22
22
23
"github.com/diamondburned/gotk4/pkg/core/closure"
23
24
"github.com/diamondburned/gotk4/pkg/core/gbox"
25
+ "github.com/diamondburned/gotk4/pkg/core/gdebug"
24
26
"github.com/diamondburned/gotk4/pkg/core/intern"
25
27
)
26
28
@@ -451,32 +453,6 @@ func SourceRemove(src SourceHandle) bool {
451
453
return gobool (C .g_source_remove (C .guint (src )))
452
454
}
453
455
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
-
480
456
// SignalHandle is the ID of a signal handler.
481
457
type SignalHandle uint
482
458
@@ -505,6 +481,7 @@ func ConnectGeneratedClosure(
505
481
userData := C .gpointer (gbox .Assign (data ))
506
482
507
483
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))
508
485
509
486
// Hold the GClosure reference.
510
487
data .GClosure = uintptr (unsafe .Pointer (gclosure ))
@@ -531,29 +508,28 @@ func ConnectGeneratedClosure(
531
508
func ConnectedGeneratedClosure (closureData uintptr ) * closure.FuncStack {
532
509
data , _ := gbox .Get (closureData ).(* generatedClosureData )
533
510
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" )
535
515
}
536
516
537
517
// Get the function value associated with this callback closure.
538
518
box := intern .TryGet (unsafe .Pointer (data .GObject ))
539
519
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" )
546
524
}
547
525
548
526
fs := box .Closures ().Load (unsafe .Pointer (data .GClosure ))
549
527
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" )
557
533
}
558
534
559
535
return fs
@@ -662,10 +638,6 @@ func newObject(ptr unsafe.Pointer, take bool) *Object {
662
638
}
663
639
}
664
640
665
- func (v * Object ) destroy () {
666
- intern .Free (v .box )
667
- }
668
-
669
641
// Cast casts v to the concrete Go type (e.g. *Object to *gtk.Entry).
670
642
//
671
643
//go:nosplit
@@ -1025,7 +997,7 @@ func marshalValue(p uintptr) (interface{}, error) {
1025
997
}
1026
998
1027
999
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 )
1029
1001
1030
1002
return & Value {v }, nil
1031
1003
}
@@ -1058,7 +1030,7 @@ func AllocateValue() *Value {
1058
1030
//An allocated GValue is not guaranteed to hold a value that can be unset
1059
1031
//We need to double check before unsetting, to prevent:
1060
1032
//`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 )
1062
1034
1063
1035
return v
1064
1036
}
0 commit comments