lilypond-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Guile GC in C++


From: Jean Abou Samra
Subject: Guile GC in C++
Date: Tue, 6 Jul 2021 10:39:48 +0200 (CEST)

Hello,

I am struggling to understand how to write
C++ code that correctly protects and unprotects
smobs from GC. Take this code from lily/grob-pq-engraver.cc:

void
Grob_pq_engraver::process_acknowledged ()
{
  std::sort (started_now_.begin (), started_now_.end ());
  SCM lst = SCM_EOL;
  SCM *tail = &lst;
  for (vsize i = 0; i < started_now_.size (); i++)
    {
      *tail = scm_acons (started_now_[i].end_.smobbed_copy (),
                         started_now_[i].grob_->self_scm (),
                         SCM_EOL);
      tail = SCM_CDRLOC (*tail);
    }

  SCM busy = get_property (this, "busyGrobs");
  busy = scm_merge_x (lst, busy, ly_grob_pq_less_p_proc);
  set_property (context (), "busyGrobs", busy);

  started_now_.clear ();
}

Looks nice, but what does SCM_CDRLOC do? It apparently
takes an SCM, and returns a pointer to an SCM. What's
the purpose? I can't find it documented anywhere
in the Guile manual (whether for 1.8 or later releases).
If I omit the call to SCM_CDRLOC, do I risk introducing
Heisenbug segmentation faults?

More generally, how does this all work? I see that when
one has an SCM at hand, one has to start caring about
GC when storing it in members (such as in engravers).
For example, if I were the author of the below code, how
would I understand that the mmrest_event_ should be
unprotected?

void
Part_combine_iterator::kill_mmrest (Context *c)
{
  if (!mmrest_event_)
    {
      mmrest_event_ = new Stream_event
      (Lily::ly_make_event_class (ly_symbol2scm ("multi-measure-rest-event")));
      set_property (mmrest_event_, "duration", SCM_EOL);
      mmrest_event_->unprotect ();
    }

  c->event_source ()->broadcast (mmrest_event_);
}

Thanks,
Jean



reply via email to

[Prev in Thread] Current Thread [Next in Thread]