[asterisk-dev] Gosub and Macro

Tilghman Lesher tilghman at mail.jeffandtilghman.com
Mon May 26 23:36:20 CDT 2008

On Monday 26 May 2008 22:12:59 Russell Bryant wrote:
> On May 26, 2008, at 12:25 PM, Atis Lezdins wrote:
> > * create app_macro_wrapper which provides the same apps as app_macro
> > but uses GoSub internally. This could be selected in menuselect by
> > default to force new users use GoSub instead, but anybody could
> > disable it and use old app_macro as before.
> I would like to see this, as well.  However, Tilghman has indicated
> that writing a Macro implementation that uses GoSub internally would
> be extremely difficult, and perhaps impossible.  Perhaps he can
> comment some more on this.

There are several ways in which Gosub and Macro differ in behavior, and
these differences are extremely difficult to emulate.  The first is what
happens when a hangup occurs.  In Macro, a hangup triggers an immediate
implicit return (or MacroExit) from every concurrently executing Macro.
Gosub, on the other hand, isn't really even executing at that point, so there
isn't a code path that exists whereby the Gosub can empty the return stack
and return to the original place.

One of the most fundamental differences between Macro and Gosub, which is the
primary reason why Macro cannot be implemented with Gosub is the behavior of a
completely different application, Goto.  If you call a Goto with a context
other than the currently executing Macro, then the Macro exits implicitly and
execution continues at the location the Goto specified.  However, as there is
no Gosub code executing at the time a Goto is executed (all Gosub really does
is to create a "gosub stack frame" which may be later referenced by Return),
it is unable to destroy the stack frame.

At a very fundamental level, Macro and Gosub are completely at odds about how
to do things.  Macro, as it continues executing until the macro ends,
specifies all sorts of behaviors that Gosub simply can't do as a standalone
lightweight subroutine generator.  Now the fact that it's lightweight means
that where Macro would fall over at a certain execution depth, Gosub can keep
going deeper.  While I can't imagine anybody going deeper than even 50 levels
deep, Gosub can reach 100,000 levels deep and keep digging.  Macro isn't very
good at going several levels deep.  It is by design limited to 7 levels deep,
although I've seen people tweak it to go 22 levels deep, and I've even seen a
crash caused by Macro going only 5 levels deep.

There are several other important differences, but those are enough to give
you an idea of just how difficult it would be to implement Macro with Gosub.

> > * ael parser could still generate macro-mymacro contexts without
> > Return, so that macros can be called. However i see that then there
> > would be troubles with accidentally having them mixed.
> > * add option for AEL parser to not replace Macro with GoSub - for
> > transitional period
> > * issue big warning in UPGRADE.txt mentioning realtime. However this
> > could create similar complains as it was recently with commas and
> > pipes.
> Does this issue really have anything to do with realtime?  I think the
> problem here is that any dialplan that works based on assumptions of
> how the AEL compiler works with respect to macros will be broken.
> This issue would exist for people calling a macro from extensions.conf
> that was implemented in extensions.ael.
> I can't imagine that this is very common, and furthermore, I would
> like to strongly discourage making any assumptions about how AEL
> compiles into traditional Asterisk extensions.

Agreed.  Trying to mix those three methods of programming the dialplan
is just asking for trouble.  It would be different if you were using AEL to
compile your dialplan to a database for realtime execution, but that's
clearly not the case.


More information about the asterisk-dev mailing list