PreviousUpNext

15.4.1116  src/lib/std/src/io/winix-mailslot-io-g.pkg

## winix-mailslot-io-g.pkg

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


stipulate
    package iox =  io_exceptions;                                                       # io_exceptions                                 is from   src/lib/std/src/io/io-exceptions.pkg
    package thk =  threadkit;                                                           # threadkit                                     is from   src/lib/src/lib/thread-kit/src/core-thread-kit/threadkit.pkg
    package xns =  exceptions;                                                          # exceptions                                    is from   src/lib/std/exceptions.pkg
herein

    # This generic is invoked (only) in:
    #
    #     src/lib/std/src/io/winix-text-file-for-os-g.pkg
    #
    generic package   winix_mailslot_io_g   (
        #             =============================
        #
        package drv:  Winix_Base_File_Io_Driver_For_Os;                                 # Winix_Base_File_Io_Driver_For_Os              is from   src/lib/std/src/io/winix-base-file-io-driver-for-os.api

        package rv:  Typelocked_Vector;                                                 # Typelocked_Vector                             is from   src/lib/std/src/typelocked-vector.api
        package rvs: Typelocked_Vector_Slice;                                           # Typelocked_Vector_Slice                       is from   src/lib/std/src/typelocked-vector-slice.api
        package wv:  Typelocked_Rw_Vector;                                              # Typelocked_Rw_Vector                          is from   src/lib/std/src/typelocked-rw-vector.api
        package wvs: Typelocked_Rw_Vector_Slice;                                        # Typelocked_Rw_Vector_Slice                    is from   src/lib/std/src/typelocked-rw-vector-slice.api

        sharing wv::Rw_Vector == wvs::Rw_Vector
                              == drv::Rw_Vector;

        sharing wv::Vector    ==  rv::Vector
                              ==  wvs::Vector
                              ==  rvs::Vector
                              ==  drv::Vector;

        sharing rvs::Slice    == wvs::Vector_Slice
                              == drv::Vector_Slice;

        sharing wvs::Slice    == drv::Rw_Vector_Slice;
      )

    : (weak)

    api {

        package drv:  Winix_Base_File_Io_Driver_For_Os;                                 # Winix_Base_File_Io_Driver_For_Os              is from   src/lib/std/src/io/winix-base-file-io-driver-for-os.api

        make_filereader:   thk::Mailslot( drv::Vector ) -> drv::Filereader;
        make_filewriter:   thk::Mailslot( drv::Vector ) -> drv::Filewriter;

    }
    {
        package drv =   drv;


        include package   threadkit;                                                    # threadkit                                     is from   src/lib/src/lib/thread-kit/src/core-thread-kit/threadkit.pkg


        vextract = rvs::to_vector o rvs::make_slice;

        # Create a reader that is connected
        # to the output port of a slot. 
        #
        fun make_filereader slot
            =
            {   closed_1shot =  make_oneshot_maildrop ();
                #
                is_closed_mailop
                    =
                    get_from_oneshot'  closed_1shot
                        ==>
                       {.  raise exception iox::CLOSED_IO_STREAM;  };

                Request
                  = READ  (Int, Mailop(Void), Mailslot(rv::Vector))
                  | CLOSE
                  ;

                request_queue
                    =
                    make_mailqueue (thk::get_current_microthread ());

                fun read_vector_mailop 0
                        =>
                        always' (rv::from_list []);

                    read_vector_mailop n
                        =>
                        {   if (n < 0)   raise exception xns::INDEX_OUT_OF_BOUNDS;              fi;
                            #
                            dynamic_mailop_with_nack
                                (\\ nack
                                    =
                                    {   reply_slot =  make_mailslot ();
                                        #
                                        put_in_mailqueue (request_queue, READ (n, nack, reply_slot));

                                        cat_mailops
                                          [
                                            take_from_mailslot'  reply_slot,
                                            is_closed_mailop
                                          ];
                                    }
                                );
                        };
                end;

                fun close ()
                    =
                    put_in_mailqueue (request_queue, CLOSE);


                fun get_data (THE v) =>   v;
                    #
                    get_data NULL
                        =>
                        {   v = take_from_mailslot slot;
                            #
                            rv::length v > 0  ??  v
                                              ::  get_data NULL;
                        };
                end;

                fun server buf
                    =
                    case (take_from_mailqueue  request_queue)
                        #
                        READ (n, nack, reply_slot)
                            =>
                            {   v = get_data buf;
                                #
                                if (rv::length v > n)
                                    #
                                    v' = vextract (v, 0, THE n);

                                    do_one_mailop [
                                        nack                  ==>   {.  server (THE v); },
                                        #       
                                        put_in_mailslot' (reply_slot, v) ==>   {.  server (THE (vextract (v, n, NULL))); }
                                     ];

                               else
                                    do_one_mailop [
                                        nack                  ==>   {.  server (THE v); },
                                        #
                                        put_in_mailslot' (reply_slot, v) ==>   {.  server NULL; }
                                    ];
                                fi;
                           };

                        CLOSE
                            =>
                            {   put_in_oneshot (closed_1shot, ());
                                #
                                closed_server ();
                            };
                    esac

                also
                fun closed_server ()
                    =
                    {   take_from_mailqueue  request_queue;
                        #
                        closed_server ();
                    };

                make_thread' [ THREAD_NAME "mailslot_io" ] server NULL;

                drv::FILEREADER
                  {
                    filename            => "<channel>", 
                    best_io_quantum     => 1024,                        #  ?? 
                    #
                    read_vector    => block_until_mailop_fires o read_vector_mailop,
                    #
                    read_vector_mailop,
                    #
                    avail      => \\ () = NULL,         #  ?? 
                    #
                    get_file_position     => NULL,
                    set_file_position     => NULL,
                    #
                    end_file_position     => NULL,
                    verify_file_position  => NULL,
                    #
                    close,
                    io_descriptor     => NULL
                  };
              };

        # Create a writer that is connected to the input port of a slot. 
        #
        fun make_filewriter ch
            =
            {   closed_1shot =  make_oneshot_maildrop ();
                #
                closed_mailop
                    =
                    get_from_oneshot'  closed_1shot
                        ==>
                        {.  raise exception iox::CLOSED_IO_STREAM;  };

                slot' = make_mailslot ();

                fun buffer ()
                    =
                    do_one_mailop [

                        take_from_mailslot' slot'
                            ==> 
                            (\\ v = {   if (rv::length v > 0)
                                           #    
                                           put_in_mailslot (ch, v);
                                        fi;

                                        buffer ();
                                    }
                            ),

                        closed_mailop
                    ];

                fun write_vector_mailop arg
                    =
                    {   v = rvs::to_vector arg;
                        #
                        cat_mailops
                          [
                            closed_mailop,

                            put_in_mailslot' (slot', v)
                                ==>
                                {. rv::length v; }
                          ];
                      };

                fun write_rw_vector_mailop  arg
                    =
                    {   v = wvs::to_vector arg;
                        #
                        cat_mailops
                          [
                            closed_mailop,

                            put_in_mailslot' (slot', v)
                                ==>
                                {. rv::length v; }
                          ];
                      };

                fun close ()
                    =
                    put_in_oneshot (closed_1shot, ());

                make_thread "mailslot io II" {.
                    #
                    buffer ();
                    #
                    ();
                };

                drv::FILEWRITER
                  {
                    filename            =>  "<channel>",
                    best_io_quantum             =>  1024,
                    #
                    write_vector                =>  block_until_mailop_fires o write_vector_mailop,
                    write_rw_vector             =>  block_until_mailop_fires o write_rw_vector_mailop,
                    #
                    write_vector_mailop,
                    write_rw_vector_mailop,
                    #
                    get_file_position      =>  NULL,
                    set_file_position      =>  NULL,
                    #
                    end_file_position      =>  NULL,
                    verify_file_position   =>  NULL,
                    #
                    close,
                    io_descriptor     =>  NULL
                  };
            };
    };
end;

## COPYRIGHT (c) 1996 AT&T Research.
## Subsequent changes by Jeff Prothero Copyright (c) 2010-2015,
## released per terms of SMLNJ-COPYRIGHT.


Comments and suggestions to: bugs@mythryl.org

PreviousUpNext