PreviousUpNext

15.4.1072  src/lib/std/src/io/threadkit-winix-mailslot-io-g.pkg

## threadkit-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
herein

    # This generic is invoked (only) in:
    #
    #     src/lib/std/src/io/threadkit-winix-text-file-for-os-g.pkg
    #
    generic package   threadkit_winix_mailslot_io_g   (
        #             =============================
        #
        package drv:  Threadkit_Winix_Base_File_Io_Driver_For_Os;                       # Threadkit_Winix_Base_File_Io_Driver_For_Os    is from   src/lib/std/src/io/threadkit-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:  Threadkit_Winix_Base_File_Io_Driver_For_Os;                       # Threadkit_Winix_Base_File_Io_Driver_For_Os    is from   src/lib/std/src/io/threadkit-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 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' closed_1shot
                        ==>
                       .{  raise exception iox::CLOSED_IO_STREAM;  };

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

                request_queue
                    =
                    make_mailqueue ();

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

                    read_vector_mailop n
                        =>
                        if (n < 0)
                            raise exception exceptions::SUBSCRIPT;
                        else
                            with_nack
                                (fn nack
                                    =
                                    {   reply_slot = make_mailslot ();
                                        #
                                        push (request_queue, READ (n, nack, reply_slot));

                                        choose [
                                            take'  reply_slot,
                                            is_closed_mailop
                                        ];
                                    }
                                );
                        fi;
                end;

                fun read_rw_vector_mailop  asl
                    =
                    {   (wvs::base  asl)
                            ->
                            (buf, i, n);

                        read_vector_mailop n
                            ==>
                            (fn v = {   wv::copy_vec { to=>buf, di=>i, from=>v };
                                        #
                                        rv::length v;
                                    }
                            );
                    };

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


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

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

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

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

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

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

                make_thread' "mailslot_io" server NULL;

                drv::FILEREADER
                  {
                    filename            => "<channel>", 
                    best_io_quantum     => 1024,                        #  ?? 
                    #
                    read_vector    => do_mailop o read_vector_mailop,
                    read_rw_vector => do_mailop o read_rw_vector_mailop,
                    #
                    read_vector_mailop,
                    read_rw_vector_mailop,
                    #
                    avail      => fn () = 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' closed_1shot
                        ==>
                        .{  raise exception iox::CLOSED_IO_STREAM;  };

                slot' = make_mailslot ();

                fun buffer ()
                    =
                    select [

                        take' slot'
                            ==> 
                            (fn v = {   if (rv::length v > 0)
                                           #    
                                           give (ch, v);
                                        fi;

                                        buffer ();
                                    }
                            ),

                        closed_mailop
                    ];

                fun write_vector_mailop arg
                    =
                    {   v = rvs::to_vector arg;
                        #
                        choose [

                            closed_mailop,

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

                fun write_rw_vector_mailop  arg
                    =
                    {   v = wvs::to_vector arg;
                        #
                        choose [

                            closed_mailop,

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

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

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

                drv::FILEWRITER
                  {
                    filename            =>  "<channel>",
                    best_io_quantum             =>  1024,
                    #
                    write_vector                =>  do_mailop o write_vector_mailop,
                    write_rw_vector             =>  do_mailop 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-2012,
## released under Gnu Public Licence version 3.


Comments and suggestions to: bugs@mythryl.org

PreviousUpNext