/* * ProcessorServer.java February 2007 * * Copyright (C) 2007, Niall Gallagher <niallg@users.sf.net> * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or * implied. See the License for the specific language governing * permissions and limitations under the License. */ package org.simpleframework.transport; import java.io.IOException; import org.simpleframework.transport.reactor.Operation; import org.simpleframework.util.thread.Daemon; /** * The <code>ProcessorServer</code> is used to convert pipelines to transports. * This simply acts as an adapter to a processor which converts a connected * pipeline to a <code>Transport</code> which can be used to read and write * data. Conversion of the pipeline is performed only once per connection. * * @author Niall Gallagher */ public class ProcessorServer implements Server { /** * This is the factory used to create the required operations. */ private final OperationFactory factory; /** * This is the processor used to process transport objects. */ private final Negotiator negotiator; /** * This is used to terminate the internals of the processor. */ private final Daemon terminator; /** * Constructor for the <code>ProcessorServer</code> object. The transport * processor is used to process plain connections and wrap those connections * in a <code>Transport</code> that can be used to send and receive data to * and from. * * @param processor * this is used to process transports */ public ProcessorServer(Processor processor) throws IOException { this(processor, 8); } /** * Constructor for the <code>ProcessorServer</code> object. The transport * processor is used to process plain connections and wrap those connections * in a <code>Transport</code> that can be used to send and receive data to * and from. * * @param processor * this is used to process transports * @param count * this is the number of threads this will use */ public ProcessorServer(Processor processor, int count) throws IOException { this(processor, count, 20480); } /** * Constructor for the <code>ProcessorServer</code> object. The transport * processor is used to process plain connections and wrap those connections * in a <code>Transport</code> that can be used to send and receive data to * and from. * * @param processor * this is used to process transports * @param count * this is the number of threads this will use * @param limit * this is the threshold for asynchronous buffers */ public ProcessorServer(Processor processor, int count, int limit) throws IOException { this.negotiator = new SecureNegotiator(processor, count); this.factory = new OperationFactory(this.negotiator, limit); this.terminator = new Terminator(processor, this.negotiator); } /** * Used to process the <code>Pipeline</code> which is a full duplex * communication link that may contain several HTTP requests. This will be * used to read the requests from the <code>Pipeline</code> and to pass * these requests to a <code>Container</code> for processing. * <p> * Typical usage of this method is to accept multiple pipeline objects, each * representing a unique HTTP channel to the client, and process requests * from those pipelines concurrently. * * @param socket * this is the connected HTTP pipeline to process */ @Override public void process(Socket socket) throws IOException { Operation task = this.factory.getInstance(socket); if (task != null) { this.negotiator.process(task); } } /** * This method is used to stop the <code>Processor</code> such that it will * accept no more pipelines. Stopping the processor ensures that all * resources occupied will be released. This is required so that all threads * are stopped, and all memory is released. * <p> * Typically this method is called once all connections to the server have * been stopped. As a final act of shutting down the entire server all * threads must be stopped, this allows collection of unused memory and the * closing of file and socket resources. * <p> * This is implemented to shut down the server asynchronously. It will start * a process to perform the shutdown. Asynchronous shutdown allows a server * resource executed via a HTTP request can stop the server without any * danger of killing itself or even worse causing a deadlock. */ @Override public void stop() throws IOException { this.terminator.start(); } }