class io.Mailslot

Overview

This class provides high-level asynchronous streaming interface for the server side of Windows mailslots which are used, for example, in SMB (Server Message Blocks) protocol and Windows Computer Browser service. More…

import "io_base.jncx"
import "io_Mailslot.jnc"

class Mailslot {
    // fields

    io.MailslotEvents readonly volatile m_activeEvents;
    std.Error const* readonly volatile m_ioError;
    bool readonly m_isOpen;

    // properties

    uint_t autoget property m_readParallelism;
    size_t autoget property m_readBlockSize;
    size_t autoget property m_readBufferSize;
    io.MailslotOptions autoget property m_options;
    uintptr_t const property m_osHandle;

    // construction

    construct();
    destruct();

    // methods

    bool errorcode open(string_t name);
    void close();

    size_t errorcode read(
        void* p,
        size_t size
    );

    long errorcode wait(
        io.MailslotEvents eventMask,
        void function* handler(io.MailslotEvents triggeredEvents)
    );

    bool errorcode cancelWait(long handle);

    io.MailslotEvents blockingWait(
        io.MailslotEvents eventMask,
        uint_t timeout = -1
    );

    import io.Mailslot.MailslotEvents async asyncWait(io.MailslotEvents eventMask);

    // aliases

    alias dispose = close;
};

Detailed Documentation

This class provides high-level asynchronous streaming interface for the server side of Windows mailslots which are used, for example, in SMB (Server Message Blocks) protocol and Windows Computer Browser service.

For working from the client side of a mailslot, please use io.File or io.FileStream.

A typical sequence of steps when working with a mailslot looks something like this:

  • Open a mailslot with open method;

  • Assign IO event handler with wait method. You would probably also want to schedule your event handler to be run in particular environment(e.g., in a specific thread) and partially apply some syncrhonization ID to discard late events;

  • When io.MailslotEvents.IncomingData event is fired, read from the mailslot using read method;

  • Close the mailslot when no longer needed with close method.

Sample code:

class MyDialog {
    // ...

    io.Mailslot m_mailslot;
    uint_t m_syncId;

    void open(string_t fileName);
    void close();
    void waitMailslotEvents();

    void onMailslotEvent(
        uint_t syncId,
        io.MailslotEvents triggeredEvents
    );
}

MyDialog.open(string_t fileName) {
    bool result = try m_mailslot.open(fileName);
    if (!result) {
        string_t errorString = std.getLastError().m_description;
        // ...
    }

    waitMailslotEvents();
}

MyDialog.close() {
    m_mailslot.close();
    m_syncId++; // events past this point will be discarded as 'late'
}

MyDialog.waitMailslotEvent() {
    io.MailslotEvents eventMask =
        io.MailslotEvents.IoError |
        io.MailslotEvents.IncomingData;

    m_mailslot.wait(eventMask, onMailslotEvent ~(++m_syncId) @
        g_mainThreadScheduler);
}

MyDialog.onMailslotEvent(
    uint_t syncId,
    io.FileStreamEvents triggeredEvents
) {
    if (syncId != m_syncId) // late event
        return;

    if (triggeredEvents & io.MailslotEvents.IoError) {
        string_t errorString = m_mailslot.m_ioError.m_description;
        // ...
    }

    if (triggeredEvents & io.MailslotEvents.IncomingData) {
        char buffer[256];
        size_t size = m_mailslot.read(buffer, sizeof(buffer));
        // ...
    }

    waitMailslotEvents(); // restart wait
}

See also:

io.MailslotEvents, io.File, io.FileStream

Fields

bool readonly m_isOpen

Holds the open status for the mailslot, i.e. true if opened; false otherwise.

Methods

bool errorcode open(string_t name)

Opens or creates a mailslot.

The function accepts a single argument, name, which is used to specify the name of the mailslot.

Returns true on success. If the mailslot could not be opened, IO error supplied by operating system is set and then the function returns false [1].

void close()

Closes a previously opened mailslot, does nothing if the mailslot is not opened. This function always succeeds.

Sometimes it may be convenient to use disposable pattern to ensure timely invokation of close [2].

size_t errorcode read(
    void* p,
    size_t size
)

Attempts to read up to size bytes from the mailslot into the buffer pointed to by p.

Returns the actual amount of bytes read or -1 if error occurs [1].

Normally you would call this function from within your event handler for IncomingData event. If this function is called when there is no incoming data, it blocks until either the data arrives, or the mailslot is closed.

Aliases

alias dispose = close

Effectively makes io.Mailslot a disposable class [2].


Footnotes