develooper Front page | perl.perl5.porters | Postings from August 2001

Adding callbacks to the core

Thread Next
From:
David M. Lloyd
Date:
August 20, 2001 11:05
Subject:
Adding callbacks to the core
Message ID:
Pine.LNX.4.33.0108201057560.1027-100000@homebody.freemm.org
I was thinking about adding functionality like that given in my
Async::Callback module directly to the core of Perl, and I want to get
some thoughts and opinions.

Specifically, I would be changing the standard 'runops' routine to look
something like this:

  int
  Perl_runops_standard(pTHX)
  {
      while ((PL_op = CALL_FPTR(PL_op->op_ppaddr)(aTHX))) {
          PERL_ASYNC_CHECK();
          PERL_CALLBACK_CHECK(); /* <-- New */
      }

      TAINT_NOT;
      return 0;
  }

Where PERL_CALLBACK_CHECK would be defined to something like:

  if (PL_callback_list_head != NULL) handle_callbacks()

And handle_callbacks() would iterate through a linked list of callbacks
that are waiting to be run (for this interpreter, I suppose).

The Perl_runops_debug would have a similar addition.

I would presume that PERL_CALLBACK_CHECK would be able to be defined to
NOOP if the user doesn't want this for some reason.

The user api would look something like this:

  CALLBACK *Perl_register_callback(void (*callback)(void *data))

    Create a new callback that can be enabled later.  Returns a pointer
    that can be used to enable, disable, or free this callback.

  void Perl_enable_callback(CALLBACK *my_cb, void *data_for_callback)

    Enable a callback that was registered before.  The callback will be
    called after the current opcode is complete, and then after every
    opcode until disable_callback is called.  The callback function will
    be passed the pointer in data_for_callback.

  void Perl_disable_callback(CALLBACK *my_cb)

    Disable a callback so that it is not called anymore until it is
    re-enabled.

  void Perl_free_callback(CALLBACK *my_cb)

    Free all resources associated with a callback.

There are good reasons to have this in the core:

1) There are many uses for such a feature.  One use is synchronization
between external (XS) modules that use threads to perform operations in
the background.  Other uses are debuggers, profilers, and coverage
modules.

2) It adds flexibility in that more than one program can use the feature
at a time, as opposed to replacing PL_runops... especially useful for
debugging modules that need to make use of callbacks.

3) The cost is small (one comparison).

4) Backwards compatibility is not lost.

My questions are:

1) Is there any reason that I should _not_ add this?

2) How should this work with ithreads/multiplicity/etc.  Right now
Async::Callback doesn't know/care about these things.  I am supposing that
each interpreter would have its own callback list, and when you add a
callback it uses the list belonging to the 'current' interpreter... does
this make sense?

Feel free to give me feedback... lots of feedback. :-)

- D

<dmlloyd@tds.net>


Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About