Search in sources :

Example 1 with IOThread

use of zmq.io.IOThread in project jeromq by zeromq.

the class SocketBase method bind.

public final boolean bind(final String addr) {
    lock();
    try {
        if (ctxTerminated) {
            errno.set(ZError.ETERM);
            return false;
        }
        options.mechanism.check(options);
        // Process pending commands, if any.
        boolean brc = processCommands(0, false, null);
        if (!brc) {
            return false;
        }
        SimpleURI uri = SimpleURI.create(addr);
        String address = uri.getAddress();
        NetProtocol protocol = checkProtocol(uri.getProtocol());
        if (protocol == null) {
            return false;
        }
        switch(protocol) {
            case inproc:
                {
                    Ctx.Endpoint endpoint = new Ctx.Endpoint(this, options);
                    boolean rc = registerEndpoint(addr, endpoint);
                    if (rc) {
                        connectPending(addr, this);
                        // Save last endpoint URI
                        options.lastEndpoint = addr;
                    } else {
                        errno.set(ZError.EADDRINUSE);
                    }
                    return rc;
                }
            case pgm:
            // continue
            case epgm:
            // continue
            case norm:
                // connect for PGM, EPGM and NORM transports.
                return connect(addr);
            case tcp:
            // continue
            case ipc:
            // continue
            case tipc:
                {
                    // Remaining transports require to be run in an I/O thread, so at this
                    // point we'll choose one.
                    IOThread ioThread = chooseIoThread(options.affinity);
                    if (ioThread == null) {
                        errno.set(ZError.EMTHREAD);
                        return false;
                    }
                    Listener listener = protocol.getListener(ioThread, this, options);
                    boolean rc = listener.setAddress(address);
                    if (!rc) {
                        listener.destroy();
                        eventBindFailed(address, errno.get());
                        return false;
                    }
                    // Save last endpoint URI
                    options.lastEndpoint = listener.getAddress();
                    addEndpoint(options.lastEndpoint, listener, null);
                    return true;
                }
            default:
                throw new IllegalArgumentException(addr);
        }
    } finally {
        unlock();
    }
}
Also used : Listener(zmq.io.net.Listener) IOThread(zmq.io.IOThread) NetProtocol(zmq.io.net.NetProtocol)

Example 2 with IOThread

use of zmq.io.IOThread in project jeromq by zeromq.

the class SocketBase method connectInternal.

private boolean connectInternal(String addr) {
    if (ctxTerminated) {
        errno.set(ZError.ETERM);
        return false;
    }
    options.mechanism.check(options);
    // Process pending commands, if any.
    boolean brc = processCommands(0, false, null);
    if (!brc) {
        return false;
    }
    SimpleURI uri = SimpleURI.create(addr);
    String address = uri.getAddress();
    NetProtocol protocol = checkProtocol(uri.getProtocol());
    if (protocol == null || !protocol.valid) {
        return false;
    }
    if (protocol == NetProtocol.inproc) {
        // TODO: inproc connect is specific with respect to creating pipes
        // as there's no 'reconnect' functionality implemented. Once that
        // is in place we should follow generic pipe creation algorithm.
        // Find the peer endpoint.
        Ctx.Endpoint peer = findEndpoint(addr);
        // The total HWM for an inproc connection should be the sum of
        // the binder's HWM and the connector's HWM.
        int sndhwm = 0;
        if (peer.socket == null) {
            sndhwm = options.sendHwm;
        } else if (options.sendHwm != 0 && peer.options.recvHwm != 0) {
            sndhwm = options.sendHwm + peer.options.recvHwm;
        }
        int rcvhwm = 0;
        if (peer.socket == null) {
            rcvhwm = options.recvHwm;
        } else if (options.recvHwm != 0 && peer.options.sendHwm != 0) {
            rcvhwm = options.recvHwm + peer.options.sendHwm;
        }
        // Create a bi-directional pipe to connect the peers.
        ZObject[] parents = { this, peer.socket == null ? this : peer.socket };
        boolean conflate = options.conflate && (options.type == ZMQ.ZMQ_DEALER || options.type == ZMQ.ZMQ_PULL || options.type == ZMQ.ZMQ_PUSH || options.type == ZMQ.ZMQ_PUB || options.type == ZMQ.ZMQ_SUB);
        int[] hwms = { conflate ? -1 : sndhwm, conflate ? -1 : rcvhwm };
        boolean[] conflates = { conflate, conflate };
        Pipe[] pipes = Pipe.pair(parents, hwms, conflates);
        // Attach local end of the pipe to this socket object.
        attachPipe(pipes[0], true);
        if (peer.socket == null) {
            // The peer doesn't exist yet so we don't know whether
            // to send the identity message or not. To resolve this,
            // we always send our identity and drop it later if
            // the peer doesn't expect it.
            Msg id = new Msg(options.identitySize);
            id.put(options.identity, 0, options.identitySize);
            id.setFlags(Msg.IDENTITY);
            boolean written = pipes[0].write(id);
            assert (written);
            pipes[0].flush();
            // If set, send the hello msg of the local socket to the peer.
            if (options.canSendHelloMsg && options.helloMsg != null) {
                written = pipes[0].write(options.helloMsg);
                assert (written);
                pipes[0].flush();
            }
            pendConnection(addr, new Ctx.Endpoint(this, options), pipes);
        } else {
            // If required, send the identity of the peer to the local socket.
            if (peer.options.recvIdentity) {
                Msg id = new Msg(options.identitySize);
                id.put(options.identity, 0, options.identitySize);
                id.setFlags(Msg.IDENTITY);
                boolean written = pipes[0].write(id);
                assert (written);
                pipes[0].flush();
            }
            // If required, send the identity of the local socket to the peer.
            if (options.recvIdentity) {
                Msg id = new Msg(peer.options.identitySize);
                id.put(peer.options.identity, 0, peer.options.identitySize);
                id.setFlags(Msg.IDENTITY);
                boolean written = pipes[1].write(id);
                assert (written);
                pipes[1].flush();
            }
            // If set, send the hello msg of the local socket to the peer.
            if (options.canSendHelloMsg && options.helloMsg != null) {
                boolean written = pipes[0].write(options.helloMsg);
                assert (written);
                pipes[0].flush();
            }
            // If set, send the hello msg of the peer to the local socket.
            if (peer.options.canSendHelloMsg && peer.options.helloMsg != null) {
                boolean written = pipes[1].write(peer.options.helloMsg);
                assert (written);
                pipes[1].flush();
            }
            if (peer.options.canReceiveDisconnectMsg && peer.options.disconnectMsg != null) {
                pipes[0].setDisconnectMsg(peer.options.disconnectMsg);
            }
            // Attach remote end of the pipe to the peer socket. Note that peer's
            // seqnum was incremented in findEndpoint function. We don't need it
            // increased here.
            sendBind(peer.socket, pipes[1], false);
        }
        // Save last endpoint URI
        options.lastEndpoint = addr;
        // remember inproc connections for disconnect
        inprocs.insert(addr, pipes[0]);
        return true;
    }
    boolean isSingleConnect = options.type == ZMQ.ZMQ_DEALER || options.type == ZMQ.ZMQ_SUB || options.type == ZMQ.ZMQ_REQ;
    if (isSingleConnect) {
        if (endpoints.hasValues(addr)) {
            // nonsensical results.
            return true;
        }
    }
    // Choose the I/O thread to run the session in.
    IOThread ioThread = chooseIoThread(options.affinity);
    if (ioThread == null) {
        errno.set(ZError.EMTHREAD);
        return false;
    }
    Address paddr = new Address(protocol, address);
    // Resolve address (if needed by the protocol)
    protocol.resolve(paddr, options.ipv6);
    // Create session.
    SessionBase session = Sockets.createSession(ioThread, true, this, options, paddr);
    assert (session != null);
    // PGM does not support subscription forwarding; ask for all data to be
    // sent to this pipe. (same for NORM, currently?)
    boolean subscribe2all = protocol.subscribe2all;
    Pipe newpipe = null;
    if (options.immediate || subscribe2all) {
        // Create a bi-directional pipe.
        ZObject[] parents = { this, session };
        boolean conflate = options.conflate && (options.type == ZMQ.ZMQ_DEALER || options.type == ZMQ.ZMQ_PULL || options.type == ZMQ.ZMQ_PUSH || options.type == ZMQ.ZMQ_PUB || options.type == ZMQ.ZMQ_SUB);
        int[] hwms = { conflate ? -1 : options.sendHwm, conflate ? -1 : options.recvHwm };
        boolean[] conflates = { conflate, conflate };
        Pipe[] pipes = Pipe.pair(parents, hwms, conflates);
        // Attach local end of the pipe to the socket object.
        attachPipe(pipes[0], subscribe2all, true);
        newpipe = pipes[0];
        // Attach remote end of the pipe to the session object later on.
        session.attachPipe(pipes[1]);
    }
    // Save last endpoint URI
    options.lastEndpoint = paddr.toString();
    addEndpoint(addr, session, newpipe);
    return true;
}
Also used : Address(zmq.io.net.Address) IZAddress(zmq.io.net.Address.IZAddress) InetSocketAddress(java.net.InetSocketAddress) Pipe(zmq.pipe.Pipe) SessionBase(zmq.io.SessionBase) IOThread(zmq.io.IOThread) NetProtocol(zmq.io.net.NetProtocol)

Example 3 with IOThread

use of zmq.io.IOThread in project jeromq by zeromq.

the class Ctx method destroy.

private void destroy() throws IOException {
    assert (sockets.isEmpty());
    for (IOThread it : ioThreads) {
        it.stop();
    }
    for (IOThread it : ioThreads) {
        it.close();
    }
    ioThreads.clear();
    selectorSync.lock();
    try {
        for (Selector selector : selectors) {
            if (selector != null) {
                selector.close();
            }
        }
        selectors.clear();
    } finally {
        selectorSync.unlock();
    }
    // Deallocate the reaper thread object.
    if (reaper != null) {
        reaper.close();
    }
    // Deallocate the array of mailboxes. No special work is
    // needed as mailboxes themselves were deallocated with their
    // corresponding io_thread/socket objects.
    termMailbox.close();
    active = false;
}
Also used : IOThread(zmq.io.IOThread) Selector(java.nio.channels.Selector)

Example 4 with IOThread

use of zmq.io.IOThread in project jeromq by zeromq.

the class Ctx method chooseIoThread.

// Returns the I/O thread that is the least busy at the moment.
// Affinity specifies which I/O threads are eligible (0 = all).
// Returns NULL if no I/O thread is available.
IOThread chooseIoThread(long affinity) {
    if (ioThreads.isEmpty()) {
        return null;
    }
    // Find the I/O thread with minimum load.
    int minLoad = -1;
    IOThread selectedIoThread = null;
    for (int i = 0; i != ioThreads.size(); i++) {
        if (affinity == 0 || (affinity & (1L << i)) > 0) {
            int load = ioThreads.get(i).getLoad();
            if (selectedIoThread == null || load < minLoad) {
                minLoad = load;
                selectedIoThread = ioThreads.get(i);
            }
        }
    }
    return selectedIoThread;
}
Also used : IOThread(zmq.io.IOThread)

Example 5 with IOThread

use of zmq.io.IOThread in project jeromq by zeromq.

the class Ctx method initSlots.

private void initSlots() {
    slotSync.lock();
    try {
        // Initialize the array of mailboxes. Additional two slots are for
        // zmq_term thread and reaper thread.
        int ios;
        optSync.lock();
        try {
            ios = ioThreadCount;
            slotCount = maxSockets + ioThreadCount + 2;
        } finally {
            optSync.unlock();
        }
        slots = new IMailbox[slotCount];
        // Initialize the infrastructure for zmq_term thread.
        slots[TERM_TID] = termMailbox;
        // Create the reaper thread.
        reaper = new Reaper(this, REAPER_TID);
        slots[REAPER_TID] = reaper.getMailbox();
        reaper.start();
        // Create I/O thread objects and launch them.
        for (int i = 2; i != ios + 2; i++) {
            IOThread ioThread = new IOThread(this, i);
            // alloc_assert (io_thread);
            ioThreads.add(ioThread);
            slots[i] = ioThread.getMailbox();
            ioThread.start();
        }
        // In the unused part of the slot array, create a list of empty slots.
        for (int i = slotCount - 1; i >= ios + 2; i--) {
            emptySlots.add(i);
            slots[i] = null;
        }
    } finally {
        slotSync.unlock();
    }
}
Also used : IOThread(zmq.io.IOThread)

Aggregations

IOThread (zmq.io.IOThread)6 SessionBase (zmq.io.SessionBase)2 NetProtocol (zmq.io.net.NetProtocol)2 IOException (java.io.IOException)1 InetSocketAddress (java.net.InetSocketAddress)1 Selector (java.nio.channels.Selector)1 ServerSocketChannel (java.nio.channels.ServerSocketChannel)1 SocketChannel (java.nio.channels.SocketChannel)1 ZError (zmq.ZError)1 StreamEngine (zmq.io.StreamEngine)1 Address (zmq.io.net.Address)1 IZAddress (zmq.io.net.Address.IZAddress)1 Listener (zmq.io.net.Listener)1 Pipe (zmq.pipe.Pipe)1