All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.rabbitmq.client.impl.nio.NioLoopContext Maven / Gradle / Ivy

Go to download

The RabbitMQ Java client library allows Java applications to interface with RabbitMQ.

There is a newer version: 5.22.0
Show newest version
// Copyright (c) 2007-2023 Broadcom. All Rights Reserved. The term "Broadcom" refers to Broadcom Inc. and/or its subsidiaries.
//
// This software, the RabbitMQ Java client library, is triple-licensed under the
// Mozilla Public License 2.0 ("MPL"), the GNU General Public License version 2
// ("GPL") and the Apache License version 2 ("ASL"). For the MPL, please see
// LICENSE-MPL-RabbitMQ. For the GPL, please see LICENSE-GPL2.  For the ASL,
// please see LICENSE-APACHE2.
//
// This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND,
// either express or implied. See the LICENSE file for specific language governing
// rights and limitations of this software.
//
// If you have any questions regarding licensing, please contact us at
// [email protected].

package com.rabbitmq.client.impl.nio;

import com.rabbitmq.client.impl.Environment;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.Selector;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ThreadFactory;

/**
 *
 */
public class NioLoopContext {

    private static final Logger LOGGER = LoggerFactory.getLogger(NioLoopContext.class);

    private final SocketChannelFrameHandlerFactory socketChannelFrameHandlerFactory;

    private final ExecutorService executorService;

    private final ThreadFactory threadFactory;

    final ByteBuffer readBuffer, writeBuffer;

    SelectorHolder readSelectorState;
    SelectorHolder writeSelectorState;

    public NioLoopContext(SocketChannelFrameHandlerFactory socketChannelFrameHandlerFactory,
        NioParams nioParams) {
        this.socketChannelFrameHandlerFactory = socketChannelFrameHandlerFactory;
        this.executorService = nioParams.getNioExecutor();
        this.threadFactory = nioParams.getThreadFactory();
        NioContext nioContext = new NioContext(nioParams, null);
        this.readBuffer = nioParams.getByteBufferFactory().createReadBuffer(nioContext);
        this.writeBuffer = nioParams.getByteBufferFactory().createWriteBuffer(nioContext);
    }

    void initStateIfNecessary() throws IOException {
        // This code is supposed to be called only from the SocketChannelFrameHandlerFactory
        // and while holding the lock.
        // We lock just in case some other code calls this method in the future.
        socketChannelFrameHandlerFactory.lock();
        try {
            if (this.readSelectorState == null) {
                this.readSelectorState = new SelectorHolder(Selector.open());
                this.writeSelectorState = new SelectorHolder(Selector.open());

                startIoLoops();
            }
        } finally {
            socketChannelFrameHandlerFactory.unlock();
        }
    }

    private void startIoLoops() {
        if (executorService == null) {
            Thread nioThread = Environment.newThread(
                threadFactory,
                new NioLoop(socketChannelFrameHandlerFactory.nioParams, this),
                "rabbitmq-nio"
            );
            nioThread.start();
        } else {
            this.executorService.submit(new NioLoop(socketChannelFrameHandlerFactory.nioParams, this));
        }
    }

    protected boolean cleanUp() {
        int readRegistrationsCount = readSelectorState.registrations.size();
        if(readRegistrationsCount != 0) {
            return false;
        }
        socketChannelFrameHandlerFactory.lock();
        try {
            if (readRegistrationsCount != readSelectorState.registrations.size()) {
                // a connection request has come in meanwhile, don't do anything
                return false;
            }

            try {
                readSelectorState.selector.close();
            } catch (IOException e) {
                LOGGER.warn("Could not close read selector: {}", e.getMessage());
            }
            try {
                writeSelectorState.selector.close();
            } catch (IOException e) {
                LOGGER.warn("Could not close write selector: {}", e.getMessage());
            }

            this.readSelectorState = null;
            this.writeSelectorState = null;
        } finally {
            socketChannelFrameHandlerFactory.unlock();
        }
        return true;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy