PreviousUpNext

15.3.384  src/lib/src/lib/thread-kit/src/core-thread-kit/mailop.api

## mailop.api
#
# Here we define the core mailop api,
# in particular the 'do_one_mailop' and '==>' fns which are the
# primary client-code interface to the mailop system via
# handle-mail-from-multiple-sources calls looking like
#
#     do_one_mailop [
#         foo' ==> {. do_this(); },
#         bar' ==> {. do_that(); }
#     ]; 

# Compiled by:
#     src/lib/std/standard.lib



###                    "Programming languages are like fairies;
###                     they are as real as you believe them to be."



api Mailop {
    #
    Mailop(X);

    Run_Gun =  Mailop(Void);                                                            # Purely for readability.
    End_Gun =  Mailop(Void);                                                            # Purely for readability.


    ###################################
    # These are the big two from the client-code perspective:
    #
    do_one_mailop:      List( Mailop(X) ) -> X;                                 # Given a list of mailops (e.g., [ foo' ==> do_this, bar' ==> do_that ]), pick at most one that is ready to run and run it.
    #                                                                           # If no mailop if ready to fire, block until one is ready to fire and then fire it. (Timeout mailops provide a way to avoid blocking indefinitely.)
    #                                                                           # Whenever multiple mailops are ready to fire, an attempt is made to pick fairly between them -- everyone gets their turn eventually.

    (==>):      (Mailop(X), X -> Y) -> Mailop(Y);                               # Given 'mailop' and 'added_action', construct a new (compound) mailop which does
                                                                                # exactly what 'mailop' does, except that afterwards it also does 'added_function'.
                                                                                #
                                                                                # This is typically used in a 'do_one_mailop' arglist, and in that context we think
                                                                                # of it and use it as an if-then rule -- hence the infix "==>" name.


    ###################################
    # These are support for imp-to-imp communications where                     # "imp" == "server microthread".  Think "tiny daemon".
    # you want zero risk of deadlock.  If you like debugging
    # erratic deadlocks you can safely skip this stuff:
    #
    Replyqueue;
    make_replyqueue:            Void -> Replyqueue;
    put_in_replyqueue:          (Replyqueue, Mailop(Void)) -> Void;
    do_one_mailop':             Replyqueue -> List( Mailop(Void) ) -> Void;     # Just like do_one_mailop, except also processes the request queue of pending replies from other imps.
    replyqueue_to_string:      (Replyqueue, String) -> String;                  # Debug support. Input string is a name for the replyqueue.



    ###################################
    # The remaining fns here are used
    # much less often in client code:

    dynamic_mailop:             (        Void   -> Mailop(X) ) -> Mailop(X);    # Make do_one_mailop [...] mailop while do_one_mailop is running.  Used in (for example):   src/lib/std/src/socket/socket.pkg
    dynamic_mailop_with_nack:   (Mailop( Void ) -> Mailop(X) ) -> Mailop(X);    # As above, but the make-mailop fn is also given a mailop used to signal client abortion of the mailop.

    never':   Mailop(X);                                                        # This mailop is never ready to fire.  Used e.g., in dynamic_mailop.

    always':  X -> Mailop(X);                                                   # This mailop is always ready to fire and simply returns its argument as the mailop value.

    if_then':    (Mailop(X), X -> Y) -> Mailop(Y);                              # A non-infix synonym for '==>'.  Given Mailop(X) and f: X -> Y, result returns f(Mailop(X)) whenever Mailop(X) fires.

    make_exception_handling_mailop
        :
        (Mailop(X), Exception -> X) -> Mailop(X);

    cat_mailops:  List( Mailop(X) ) -> Mailop(X);                               # Combine a list of mailops into a single mailop.  A frequent idiom is:  block_until_mailop_fires (cat_mailops mailops);

    block_until_mailop_fires:     Mailop(X) -> X;                               # Run an individual mailop without bothering with a full do_one_mailop [...] statement.
                                                                                # Typically used to block until the mailop fires, hence the name.
};



## COPYRIGHT (c) 1989-1991 John H. Reppy
## COPYRIGHT (c) 1995 AT&T Bell Laboratories.
## Subsequent changes by Jeff Prothero Copyright (c) 2010-2015,
## released per terms of SMLNJ-COPYRIGHT.


Comments and suggestions to: bugs@mythryl.org

PreviousUpNext