Skip to content

gtk: allocate Gtk memory with 'atomic-interior - #375

Merged
samth merged 1 commit into
racket:masterfrom
samth:gtk-atomic-interior
Oct 20, 2026
Merged

samth merged 1 commit into
racket:masterfrom
samth:gtk-atomic-interior

Conversation

@samth

@samth samth commented Oct 19, 2026

Copy link
Copy Markdown
Member

It's possible to call back into Racket during a Gtk call, via logging, signal handling, and other operations. If the Racket code triggers a collection, Gtk structs could move in the heap, leading to a crash. Avoid that by using 'atomic-interior mode with all the data that Gtk can reach.

@samth

samth commented Oct 19, 2026

Copy link
Copy Markdown
Member Author

This won't pass on CI until tomorrow, because it needs the FFI type added in racket/racket#5617.

It's possible to call back into Racket during a Gtk call, via logging,
signal handling, and other operations. If the Racket code triggers a
collection, Gtk structs could move in the heap, leading to a crash.
Avoid that by using `'atomic-interior` mode with all the data that Gtk
can reach.
@samth
samth force-pushed the gtk-atomic-interior branch from 016dbf4 to 4dd4cc3 Compare October 20, 2026 17:43

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Resyntax analyzed 22 files in this pull request and has added suggestions.

(define-gtk gtk_tree_view_get_visible_range (_fun _GtkWidget [sp : (_ptr o _pointer)] [ep : (_ptr o _pointer)]
(define-gtk gtk_tree_view_get_visible_range (_fun _GtkWidget [sp : (_ptr o _pointer atomic-interior)] [ep : (_ptr o _pointer atomic-interior)]
-> [ok? : _gboolean]
-> (values (if ok? sp #f) (if ok? ep #f))))

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if-else-false-to-and: This if expression can be refactored to an equivalent expression using and.

Suggested change
-> (values (if ok? sp #f) (if ok? ep #f))))
-> (values (and ok? sp) (if ok? ep #f))))
Debugging details
Textual replacement
(line-replacement
  #:new-lines
    '#("                                                  -> (values (and ok? sp) (if ok? ep #f))))")
  #:original-lines
    '#("                                                  -> (values (if ok? sp #f) (if ok? ep #f))))")
  #:start-line 89)
Syntactic replacement
(syntax-replacement
  #:introduction-scope #<procedure:...and/syntax-local.rkt:148:2>
  #:new-syntax
    #<syntax:/home/runner/.local/share/racket/9.4.0.2/pkgs/resyntax/default-recommendations/boolean-shortcuts.rkt:63:2 (and ok? sp)>
  #:original-syntax
    #<syntax:gui-lib/mred/private/wx/gtk/list-box.rkt:89:61 (if ok? sp #f)>
  #:source
    (file-source
     #<path:/home/runner/work/gui/gui/gui-lib/mred/private/wx/gtk/list-box.rkt>)
  #:uses-universal-tagged-syntax? #f)

(define-gtk gtk_tree_view_get_visible_range (_fun _GtkWidget [sp : (_ptr o _pointer)] [ep : (_ptr o _pointer)]
(define-gtk gtk_tree_view_get_visible_range (_fun _GtkWidget [sp : (_ptr o _pointer atomic-interior)] [ep : (_ptr o _pointer atomic-interior)]
-> [ok? : _gboolean]
-> (values (if ok? sp #f) (if ok? ep #f))))

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if-else-false-to-and: This if expression can be refactored to an equivalent expression using and.

Suggested change
-> (values (if ok? sp #f) (if ok? ep #f))))
-> (values (if ok? sp #f) (and ok? ep))))
Debugging details
Textual replacement
(line-replacement
  #:new-lines
    '#("                                                  -> (values (if ok? sp #f) (and ok? ep))))")
  #:original-lines
    '#("                                                  -> (values (if ok? sp #f) (if ok? ep #f))))")
  #:start-line 89)
Syntactic replacement
(syntax-replacement
  #:introduction-scope #<procedure:...and/syntax-local.rkt:148:2>
  #:new-syntax
    #<syntax:/home/runner/.local/share/racket/9.4.0.2/pkgs/resyntax/default-recommendations/boolean-shortcuts.rkt:63:2 (and ok? ep)>
  #:original-syntax
    #<syntax:gui-lib/mred/private/wx/gtk/list-box.rkt:89:76 (if ok? ep #f)>
  #:source
    (file-source
     #<path:/home/runner/work/gui/gui/gui-lib/mred/private/wx/gtk/list-box.rkt>)
  #:uses-universal-tagged-syntax? #f)

Comment on lines +184 to +190
(for ([str (in-list types)]
[i (in-naturals)])
(let ([t (ptr-add targets i _GtkTargetEntry)])
(cpointer-push-tag! t 'GtkTargetEntry)
(set-GtkTargetEntry-target! t (ptr-add target-strings offset))
(set-GtkTargetEntry-target! t str)
(set-GtkTargetEntry-flags! t 0)
(set-GtkTargetEntry-info! t i))
(let ([bstr (string->bytes/utf-8 str)])
(memcpy target-strings offset bstr 0 (bytes-length bstr))
(let ([offset (+ offset (bytes-length bstr))])
(ptr-set! (ptr-add target-strings offset) _byte 0)
(+ offset 1))))
(set-GtkTargetEntry-info! t i)))

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let-to-define: Internal definitions are recommended instead of let expressions, to reduce nesting.

Suggested change
(for ([str (in-list types)]
[i (in-naturals)])
(let ([t (ptr-add targets i _GtkTargetEntry)])
(cpointer-push-tag! t 'GtkTargetEntry)
(set-GtkTargetEntry-target! t (ptr-add target-strings offset))
(set-GtkTargetEntry-target! t str)
(set-GtkTargetEntry-flags! t 0)
(set-GtkTargetEntry-info! t i))
(let ([bstr (string->bytes/utf-8 str)])
(memcpy target-strings offset bstr 0 (bytes-length bstr))
(let ([offset (+ offset (bytes-length bstr))])
(ptr-set! (ptr-add target-strings offset) _byte 0)
(+ offset 1))))
(set-GtkTargetEntry-info! t i)))
(for ([str (in-list types)]
[i (in-naturals)])
(define t (ptr-add targets i _GtkTargetEntry))
(cpointer-push-tag! t 'GtkTargetEntry)
(set-GtkTargetEntry-target! t str)
(set-GtkTargetEntry-flags! t 0)
(set-GtkTargetEntry-info! t i))
Debugging details
Textual replacement
(line-replacement
  #:new-lines
    '#("          (for ([str (in-list types)]"
       "                [i (in-naturals)])"
       "            (define t (ptr-add targets i _GtkTargetEntry))"
       "            (cpointer-push-tag! t 'GtkTargetEntry)"
       "            (set-GtkTargetEntry-target! t str)"
       "            (set-GtkTargetEntry-flags! t 0)"
       "            (set-GtkTargetEntry-info! t i))")
  #:original-lines
    '#("          (for ([str (in-list types)]"
       "                [i (in-naturals)])"
       "            (let ([t (ptr-add targets i _GtkTargetEntry)])"
       "              (cpointer-push-tag! t 'GtkTargetEntry)"
       "              (set-GtkTargetEntry-target! t str)"
       "              (set-GtkTargetEntry-flags! t 0)"
       "              (set-GtkTargetEntry-info! t i)))")
  #:start-line 184)
Syntactic replacement
(syntax-replacement
  #:introduction-scope #<procedure:...and/syntax-local.rkt:148:2>
  #:new-syntax
    #<syntax:.../resyntax/base.rkt:215:28 (for ((str (in-list types)) (i (in-naturals))) (define t (ptr-add targets i _GtkTargetEntry)) (cpointer-push-tag! t (quote GtkTargetEntry)) (set-GtkTargetEntry-target! t str) (set-GtkTargetEntry-flags! t 0) (set-GtkTargetEntry-info! t i))>
  #:original-syntax
    #<syntax:gui-lib/mred/private/wx/gtk/clipboard.rkt:184:10 (for ((str (in-list types)) (i (in-naturals))) (let ((t (ptr-add targets i _GtkTargetEntry))) (cpointer-push-tag! t (quote GtkTargetEntry)) (set-GtkTargetEntry-target! t str) (set-GtkTargetEntry-flags! t 0) (set-GtkTargetEntry-info! t i)))>
  #:source
    (file-source
     #<path:/home/runner/work/gui/gui/gui-lib/mred/private/wx/gtk/clipboard.rkt>)
  #:uses-universal-tagged-syntax? #f)

@mflatt

mflatt commented Oct 20, 2026

Copy link
Copy Markdown
Member

This looks right to me.

@samth
samth merged commit 9ec6913 into racket:master Oct 20, 2026
2 checks passed
@samth
samth deleted the gtk-atomic-interior branch October 20, 2026 19:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants