PreviousUpNext

15.4.1145  src/lib/std/src/posix/winix-io.pkg

## winix-io.pkg

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


# A subpackage of winix_guts:
#
#     src/lib/std/src/posix/winix-guts.pkg


stipulate
    package unt =  unt_guts;                                    # unt_guts                              is from   src/lib/std/src/bind-unt-guts.pkg
    package i1w =  one_word_int_guts;                           # one_word_int_guts                     is from   src/lib/std/src/one-word-int-guts.pkg
    package int =  int_guts;                                    # int_guts                              is from   src/lib/std/src/bind-int-32.pkg
    package psx =  posix_1003_1b;                               # posix_1003_1b                         is from   src/lib/std/src/posix-1003.1b/posix-1003-1b.pkg
    package ci  =  mythryl_callable_c_library_interface;        # mythryl_callable_c_library_interface  is from   src/lib/std/src/unsafe/mythryl-callable-c-library-interface.pkg
herein

    package   winix_io
    : (weak)  Winix_Io                                          # Winix_Io                              is from   src/lib/std/src/winix/winix-io.api
    {
        # An Io_Descriptor is an abstract descriptor
        # for an OS chunk that supports I/O
        # (e.g., file, tty device, socket, ...).
        #
        Io_Descriptor
            =
            winix_types::io::Io_Descriptor;

        Io_Descriptor_Kind
            =
            KIND  String;


        # Return a hash value for the I/O descriptor:
        #
        fun hash fd
            =
            unt::from_int (winix_types::io::iod_to_fd fd);


        # Compare two I/O descriptors:
        #
        fun compare (fd1, fd2)
            =
            int::compare
                ( winix_types::io::iod_to_fd  fd1,
                  winix_types::io::iod_to_fd  fd2
                );


        package kind {
            #
            file    =  KIND "FILE";
            dir     =  KIND "DIR";
            symlink =  KIND "LINK";
            tty     =  KIND "TTY";
            pipe    =  KIND "PIPE";
            socket  =  KIND "SOCKET";
            device  =  KIND "DEV";
        };

        # Return the kind of I/O descriptor:

        fun kind io_descriptor
            =
            {
                i    = winix_types::io::iod_to_fd  io_descriptor;
                fd   = psx::int_to_fd    i;
                stat = psx::fstat        fd;

                if   (psx::stat::is_file       stat)  kind::file;
                elif (psx::stat::is_directory  stat)  kind::dir;
                elif (psx::stat::is_char_dev   stat)  kind::tty;
                elif (psx::stat::is_block_dev  stat)  kind::device; #  ?? 
                elif (psx::stat::is_symlink    stat)  kind::symlink;
                elif (psx::stat::is_pipe       stat)  kind::pipe;
                elif (psx::stat::is_socket     stat)  kind::socket;
                else                                  KIND "UNKNOWN";
                fi;
            };

        Wait_Request
          =
          { io_descriptor:      Io_Descriptor,
            readable:           Bool,
            writable:           Bool,
            oobdable:           Bool                                                            # Out-Of-Band-Data available on socket or PTY.
          };
          # Public representation of a polling operation on
          # an I/O descriptor.

        Wait_Result     = Wait_Request;                                                         # A synonym to clarify declarations.

        exception BAD_WAIT_REQUEST;



        # 'wait_for_io_opportunity' tests which fds
        # (of a given set)
        # are ready for I/O:
        #
        stipulate

            poll' =  ci::find_c_function { lib_name => "posix_os", fun_name => "poll" }         # poll          def in   src/c/lib/posix-os/poll.c
                :
                ( (List( (Int, Unt) ),                                                          # (fd, flags) pairs where 'flags' has three bits: readable/writable/oobdable
                  Null_Or( (i1w::Int, Int) ))                                                   # NULL or (THE timeout), where 'timeout' is a (seconds, microseconds) pair.
                )
                ->
                List( (Int, Unt) )                                                              # Result list of (fd, flags) pairs, where 'flags' is nonzero (if zero, the pair is dropped from the result list).
                ;

            fun conditional_bit_or (FALSE,   _, accumulator) =>  accumulator;
                conditional_bit_or (TRUE,  bit, accumulator) =>  unt::bitwise_or (accumulator, bit);
            end;

            fun test (word, bit)
                =
                (unt::bitwise_and (word, bit) != 0u0);

            readable_bit =  0u1;
            writable_bit =  0u2;
            oobdable_bit =  0u4;

            fun from_wait_request { io_descriptor, readable, writable, oobdable }
                =
                ( winix_types::io::iod_to_fd  io_descriptor,

                  conditional_bit_or
                    (
                      readable,
                      readable_bit,

                      conditional_bit_or
                        (
                          writable,
                          writable_bit,

                          conditional_bit_or
                            (
                              oobdable,
                              oobdable_bit,
                              0u0
                            )
                        )
                    )
                );


            fun to_poll_result (fd, w)
                =
                { io_descriptor =>  winix_types::io::int_to_iod  fd,
                  readable      =>  test (w, readable_bit),
                  writable      =>  test (w, writable_bit),
                  oobdable      =>  test (w, oobdable_bit)
                };

        herein


            fun wait_for_io_opportunity { wait_requests, timeout }
                =
                {
                    timeout
                        =
                        case timeout
                            #
                            THE time
                                =>
                                {
                                    usec = time_guts::to_microseconds  time;
                                    #
                                    (multiword_int_guts::div_mod (usec, 1000000))
                                        ->
                                        (sec, usec);

                                    THE (i1w::from_multiword_int sec, int::from_multiword_int usec);
                                };

                            NULL =>
                                {
                                    NULL;
                                };
                        esac;

                    raw_results =  poll' (list::map from_wait_request wait_requests, timeout);

                    list::map
                        to_poll_result
                        raw_results;
                  };

            select = wait_for_io_opportunity;
                #
                # Deprecated synonym for 'wait_for_io_opportunity', mainly so
                # that unix folks looking for 'select' in the function index
                # will get led here.

        end;                                                                                            # stipulate
    };                                                                                                  # package winix_io 
end;



Comments and suggestions to: bugs@mythryl.org

PreviousUpNext