Next Previous Contents

26. Network I/O

The networking I/O layer is responsible for all network I/O (duh!).

It is implemented as a set of asyncronous operations for opening / acception connections and reading/writing data on those connections. The asyncronous operation means that each API call will only initiate the operation, and when the operation s finished a supplied callback function will be called.

Created filehandles are cbdata enabled, and any links / pointers to filehandles should be properly managed as cbdata.

The return value of is 0 on success or -1 on error. On error, errno will be set to a suitable error code.

All data is contained in IOBuf handlers. Each IOBuf has a reference count, knows the amount of data stored in the IOBuf, actual size of the allocated buffer area (internal) and the buffer area itself. IOBuf is not a simple pointer.

26.1 API

This are the functions available for performing network I/O operations

ncomm_close

        int
        ncomm_close(filehandle *fh);

Signals EOF on the socket. No further ncomm_write calls is allowed after this.

Any pending I/O operations will be completed.

The socket will get fully closed when the last reference to the filehandle is gone.

ncomm_closed

        int
        ncomm_closed(filehandle *fh);

Returns true if a filehandle has been closed with ncomm_close()

ncomm_abort

What should we do with callbacks?

        int
        ncomm_abort(filehandle *fh);

Aborts the given network connection immediately. Any pending I/O requests will be aborted. No callbacks will be done for cancelled I/O requests.

ncomm_listen

        filehandle *
        ncomm_listen(int sock_type, int proto, struct sockaddr *where,
                     int addrsize, int backlog, COMMNEWCB *callback,
                     void *cbdata)

start listening for new connections on the given address/port.

The listening port is open until closed with ncomm_close or aborted with ncomm_abort. comm_abort will cancel any pending queued incoming connections not yet notified to the callback, while ncomm_close will only stop listening for new connection requests.

ncomm_accept

        filehandle *
        ncomm_accept(int sock_type, int proto, struct sockaddr *where,
                     struct sockaddr *from, int addrsize,
                     COMMNEWCB callback, void *cbdata)

Accept a single connection from the given source

The returned filehandle is not valid for use until the callback has been notified, except for comm_abort to cancel the connection request.

ncomm_connect

        filehandle *
        ncomm_connect(int sock_type, int proto,
                      const struct sockaddr *local,
                      const struct sockaddr *remote, int addrsize,
                      COMMNEWCB *callback, void *cbdata)

Creates a new network connection to the given remote address, optionally using a specified local source address.

The returned filehandle is not valid for use until the callback has been notified, except for comm_abort to cancel the connection request.

ncomm_read

        void
        ncomm_read(filehandle *fh, COMMIOCB *callback, void *cbdata);
        void
        ncomm_read_limited(filehandle *fh, size_t max_size, COMMIOCB *callback,
                   void *cbdata);

Request to write data. The callback will be called when the request has finished, or if an unrecoverable error occurs.

ncomm_read_limited can limit the max amount of data read in one request.

Any errors will be signalled to the callback function.

ncomm_write

        void
        ncomm_write(filehandle *fh, IOBUF *buf, COMMIOCB *callback,
                    void *cbdata);

Request to write data. The callback will be called when the request has finished, or if an unrecoverable error occurs.

it is allowable to queue more write requests before the first has finished. The requests will be processed and completed in the order requested without reordering in data or callback order.

Any errors will be signalled to the callback function.

ncomm_write_fragment

        void
        ncomm_write_fragment(filehandle *fh, IOBUF *buf, off_t offset,
                    size_t size, COMMIOCB *callback, void *cbdata);

as ncomm_write, but only writes the indicated range of the supplied IOBuf.

ncomm_write_mbuf

        void
        ncomm_write_mbuf(filehandle *fh, MemBuf mb, COMMIOCB *callback,
                         void *cbdata);

Like comm_write, but gets the data from a MemBuf instead of a IOBuf.

The MemBuf should not be used after this. The responsibility for the data area is taken over by ncomm.

ncomm_add_close_handler

        int
        ncomm_add_close_handler(filehandle *fh, COMMCLOSECB *handler,
                                void *cbdata);

Registers a close handler what will be called when the socket is closed. For example to clean up associated data structures or keep relations proper.

26.2 callbacks

Callbacks are used to get notifications when an network operation has finished. These functions are passed as arguments to the I/O operation to be performed, and will get called when the operation finishes (completed or error).

COMMNEWCB

        typedef void
        COMMNEWCB(filehandle *fh, int error, struct sockaddr *local,
                  struct sockaddr *peer, int addrsize, void *cbdata);

Called when a new filehandle is created (ncomm_listen / ncomm_accept / ncomm_connect)

On error, error is set to the appropriate errno.

COMMIOCB

        typedef void
        COMMIOCB(filehandle *fh, IOBUF *buf, int offset, int size,
                 int errno, void *cbdata);

Called when an I/O operation has finished (ncomm_read / ncomm_write).

On error errno will be set to the error, otherwise errno will be 0.

offset is the offset in the IOBUF where the data for the operation starts, and size is the amount of data processed by the operation.

Note: On error the operation might have been partially completed. In such case size >= 0 and errno != 0.

COMMCLOSECB

        typedef void
        COMMCLOSECB(filehandle *fh, void *cbdata);

Called when the filehandle is closed (ncomm_close / ncomm_abort), as requested (ncomm_add_close_handler)

26.3 "system" API

These functions are part of the general framework, and are generally only called once, at suitable locations in the program.

ncomm_handle_events

        void
        ncomm_handle_events(int timeout);

This is the network I/O "main loop". Will execute any pending I/O events, and if no events are pending optionally wait for timeout milliseconds for an event to arrive.

ncomm_module_init

        void
        ncomm_module_init(void);

Initializes the network I/O subsystem

ncomm_module_shutdown

        void
        ncomm_module_shutdown(void);

Called on shutdown. Terminates all pending I/O operations and/or connections and other related cleanups.

ncomm_abort_all_connections

Do we really need this?

        void
        ncomm_abort_all_connections(void);

Aborts all currently open network connections.

26.4 Internal "poll" API

The "poll" API can be used on UNIX to implement event notification mechanisms without having to reimplement all the read/write logics. The purpose of this "event" system is to notify the generic read/write logics when I/O is possible on a socket.

comm_register_for_read_event

        void
        comm_register_for_read_event(filehandle *fh, COMMEVENTREAD *handler);

Ask to receive read events on the filehandle "fh". When there is a read event available, "handler" will be called.

COMMEVENTREAD

        typedef int COMMEVENTREAD(filehandle *fh);

Callback function type for receiving read event notifications

comm_register_for_write_event

        void
        comm_register_for_write_event(filehandle *fh, COMMEVENTWRITE *handler);

Ask to receive write events on the filehandle "fh". When writing is possible, "handler" will get called.

COMMEVENTWRITE

        typedef int COMMEVENTWRITE(filehandle *fh);

Callback function type for receiving write event notifications


Next Previous Contents