PreviousUpNext

15.4.1104  src/lib/std/src/io/io-startup-and-shutdown–premicrothread.pkg

## io-startup-and-shutdown--premicrothread.pkg
#
# This package tracks open I/O streams and
# does startup/shutdown stuff like closing
# them on exit.
#
# NOTE: there is currently a problem with removing
# the at-functions for streams that get dropped
# by the application, but the system limit on
# open files will limit this.                           XXX BUGGO FIXME

# Compiled by:
#     src/lib/std/src/standard-core.sublib


stipulate
    package at  =  run_at__premicrothread;                                                              # run_at__premicrothread                        is from   src/lib/std/src/nj/run-at--premicrothread.pkg
herein

    package io_startup_and_shutdown__premicrothread
    :       Io_Startup_And_Shutdown__Premicrothread                                                     # Io_Startup_And_Shutdown__Premicrothread       is from   src/lib/std/src/io/io-startup-and-shutdown--premicrothread.api
    {
        Tag = Ref( Void );                                                                              # Here we use refcells as ids, taking advantage of the fact that every refcell equals itself but does not equal any other refcell:
                                                                                                        # saves us the bother of setting up a counter to issue unique small integers, protecting that counter with a mutex etc etc.
        Stream_Startup_And_Shutdown_Actions
          =
          {
            tag:    Tag,                #  Unique ID for this cleaner.
            init:   Void -> Void,       #  Called for at::STARTUP_PHASE_5_CLOSE_STALE_OUTPUT_STREAMS
            flush:  Void -> Void,       #  Called for at::SHUTDOWN_PHASE_6_FLUSH_OPEN_FILES
            close:  Void -> Void        #  Called for at::SHUTDOWN_PHASE_6_CLOSE_OPEN_FILES
          };

        per_stream_startup_and_shutdown_actions
            =
            REF ([]:  List( Stream_Startup_And_Shutdown_Actions ));

# 'note_stream_startup_and_shutdown_actions'?
        fun note_stream_startup_and_shutdown_actions { init, flush, close }
            =
            {   tag = REF ();
                #
                per_stream_startup_and_shutdown_actions
                    :=
                    { tag, init, flush, close }  !  *per_stream_startup_and_shutdown_actions;

                tag;
            };

        fun get_tag ( { tag, ... } : Stream_Startup_And_Shutdown_Actions)                               # Internal function.
            =
            tag;

# 'change_stream_startup_and_shutdown_actions'?
        fun change_stream_startup_and_shutdown_actions (t, { init, flush, close } )
            =
            per_stream_startup_and_shutdown_actions := f *per_stream_startup_and_shutdown_actions
            where
                fun f (x ! r)
                        =>
                        {   t' = get_tag x;
                            #
                            if (t' == t)  { tag=>t, init, flush, close }  !   r;
                            else                                       x  ! f r;
                            fi;
                        };

                    f [] =>  raise exception DIE "change_stream_startup_and_shutdown_actions: tag not found";
                end;
            end;

        fun drop_stream_startup_and_shutdown_actions  tag
            =
            per_stream_startup_and_shutdown_actions
                :=
                f *per_stream_startup_and_shutdown_actions                                                      # Should really just use filter/remove from  src/lib/std/src/list.api
            where
                fun f (cleaner ! rest) =>   if (get_tag cleaner == tag)               rest;                     # Drop actions from action list.
                                            else                         cleaner !  f rest;                     # Keep actions in   action list, process rest of list recursively.
                                            fi;

                    f []               =>   [];                                                                 # Done!
                end;
            end;


        fun run_action_on_all_known_streams  field_fn
            =
            loop *per_stream_startup_and_shutdown_actions
            where
                fun loop (x ! r)
                        =>
                        {   ((field_fn x) ())
                            except
                                _ = ();

                            loop r;
                        };

                    loop [] =>  ();
                end;
            end;

                                            # run_at__premicrothread            is from   src/lib/std/src/nj/run-at--premicrothread.pkg



# case (winix__premicrothread::process::get_env "FOO")  THE string => ... ; NULL => ... esac;


                                                                        my _ = 
        at::schedule
          (
            "io-startup-and-shutdown--premicrothread.pkg: .close streams",              # Text label for debugging displays.
                                
            [ at::SHUTDOWN_PHASE_6_CLOSE_OPEN_FILES ],                  # When to run the function.
  
            \\ _ = {                                                    # Ignored arg is at::SHUTDOWN_PHASE_6_CLOSE_OPEN_FILES.
                log::log_note__hook := NULL;                    # Try to stop us from crashing on write-to-dead-fd on "mythryl.log".
                log::log_warn__hook := NULL;                    # Try to stop us from crashing on write-to-dead-fd on "mythryl.log".
#               log::log_fatal__hook := NULL;                   # Commented out because it is no longer Null_Or(...)
                                                                        # log   is from   src/lib/std/src/log.pkg
# print "FUBAR:  run_action_on_all_known_streams .close;   -- io-startup-and-shutdown--premicrothread.pkg/at::SHUTDOWN_PHASE_6_CLOSE_OPEN_FILES/AAA\n";
                 run_action_on_all_known_streams .close;
# print "FUBAR:  run_action_on_all_known_streams .close;   -- io-startup-and-shutdown--premicrothread.pkg/at::SHUTDOWN_PHASE_2_CLOSE_OPEN_FILES/ZZZ\n";
            }
          );

                                                                        my _ = 
        at::schedule
          (
            "io-startup-and-shutdown--premicrothread.pkg: .flush streams",              # Text label for debugging displays.
                                
            [ at::SHUTDOWN_PHASE_6_FLUSH_OPEN_FILES ],                  # When to run the function.
  
            \\ _ = {                                                    # Ignored arg is at::SHUTDOWN_PHASE_6_FLUSH_OPEN_FILES.
# print "FUBAR:  run_action_on_all_known_streams .flush;   -- io-startup-and-shutdown--premicrothread.pkg/at::STARTUP_PHASE_4_FLUSH_OPEN_FILES/AAA\n";
                 run_action_on_all_known_streams .flush;
# print "FUBAR:  run_action_on_all_known_streams .flush;   -- io-startup-and-shutdown--premicrothread.pkg/at::STARTUP_PHASE_4_FLUSH_OPEN_FILES/ZZZ\n";
            }
          );

                                                                        my _ = 
        at::schedule
          (
            "io-startup-and-shutdown--premicrothread.pkg: .init streams",               # Text label for debugging displays.
                                
            [ at::STARTUP_PHASE_5_CLOSE_STALE_OUTPUT_STREAMS ],         # When to run the function.
  
            \\ _ = {                                                    # Ignored arg is at::STARTUP_PHASE_5_CLOSE_STALE_OUTPUT_STREAMS
# print "FUBAR:  run_action_on_all_known_streams .init;   -- io-startup-and-shutdown--premicrothread.pkg/at::STARTUP_PHASE_5_CLOSE_STALE_OUTPUT_STREAMS/AAA\n";
                 run_action_on_all_known_streams .init;
# print "FUBAR:  run_action_on_all_known_streams .init;   -- io-startup-and-shutdown--premicrothread.pkg/at::STARTUP_PHASE_5_CLOSE_STALE_OUTPUT_STREAMS/ZZZ\n";
            }
          );



    };                                                          # package io_startup_and_shutdown__premicrothread
end;



Comments and suggestions to: bugs@mythryl.org

PreviousUpNext