Jean Abou Samra <[email protected]> writes:

>  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_); 
>  } 

Uh, after the call to mmrest_event_->unprotect () there is nothing that
would protect the newly created mmrest_event_ .  This is just hoping
that the first of the functions that this broadcast to will protect it
before any allocation occurs.

In short, yes, this is potentially a bad Heisenbug.  The proper way
would be to unprotect after the broadcast call, or to convert
mmrest_event_ to an SCM value and do an scm_remember_upto_here_1 call on
it after the broadcast.

A better interface would have been to let broadcast take an SCM value:
that way it can keep the SCM value alive until it doesn't need it
anymore and the caller does not need to keep it live in some contorted
manner.

-- 
David Kastrup

Reply via email to