You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hc.apache.org by ol...@apache.org on 2006/02/06 21:30:01 UTC

svn commit: r375356 [2/2] - in /jakarta/httpcomponents/trunk/http-async: ./ src/ src/examples/ src/examples/org/ src/examples/org/apache/ src/examples/org/apache/http/ src/examples/org/apache/http/examples/ src/java/ src/java/org/ src/java/org/apache/ ...

Added: jakarta/httpcomponents/trunk/http-async/src/java/org/apache/http/async/impl/SimpleHttpDispatcher.java
URL: http://svn.apache.org/viewcvs/jakarta/httpcomponents/trunk/http-async/src/java/org/apache/http/async/impl/SimpleHttpDispatcher.java?rev=375356&view=auto
==============================================================================
--- jakarta/httpcomponents/trunk/http-async/src/java/org/apache/http/async/impl/SimpleHttpDispatcher.java (added)
+++ jakarta/httpcomponents/trunk/http-async/src/java/org/apache/http/async/impl/SimpleHttpDispatcher.java Mon Feb  6 12:29:56 2006
@@ -0,0 +1,549 @@
+/*
+ * $HeadURL$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ *
+ *  Copyright 2006 The Apache Software Foundation
+ *
+ *  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.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+
+package org.apache.http.async.impl;
+
+
+import java.io.IOException;
+import java.util.List;
+import java.util.LinkedList;
+import java.util.Collection;
+
+import org.apache.http.HttpRequest;
+import org.apache.http.HttpEntityEnclosingRequest;
+import org.apache.http.HttpResponse;
+import org.apache.http.HttpMutableResponse;
+import org.apache.http.HttpEntity;
+import org.apache.http.HttpHost;
+import org.apache.http.HttpClientConnection;
+import org.apache.http.ConnectionReuseStrategy;
+import org.apache.http.HttpException;
+import org.apache.http.protocol.HttpContext;
+import org.apache.http.params.HttpParams;
+import org.apache.http.async.HttpHandle;
+import org.apache.http.async.HttpDispatcher;
+import org.apache.http.async.AsyncHttpProcessor;
+import org.apache.http.async.AbstractHttpHandle;
+import org.apache.http.async.AbstractHttpDispatcher;
+
+
+
+/**
+ * Minimal implementation of an {@link HttpDispatcher HttpDispatcher}.
+ * This dispatcher uses a single connection and background thread.
+ * Requests are dispatched in order. The background thread switches
+ * from sending a request to receiving the response and notifying.
+ * Request execution is therefore serialized.
+ * <br/>
+ * If synchronization has to be nested, the required locks MUST be
+ * obtained in the following order to prevent deadlocks:
+ * <ol>
+ * <li><code>this</code></li>
+ * <li>{@link AbstractHttpDispatcher#linked_handle_monitor
+ *            linked_handle_monitor}</li>
+ * <li>{@link #request_handle_monitor request_handle_monitor}</li>
+ * <li>{@link #response_handle_monitor response_handle_monitor}</li>
+ * </ol>
+ *
+ * @version $Revision$ $Date$
+ * 
+ * @since 4.0
+ */
+public class SimpleHttpDispatcher extends AbstractHttpDispatcher
+    implements HttpDispatcher {
+    // @@@ move some of this stuff to an abstract base class?
+
+    /** The one and only connection. */
+    private final HttpClientConnection client_connection;
+
+    /**
+     * The HTTP processor.
+     * For pre- and postprocessing of requests and responses, respectively.
+     */
+    protected final AsyncHttpProcessor async_processor;
+
+    /** The connection re-use strategy. */
+    private ConnectionReuseStrategy reuse_strategy;
+
+    /** The parameters to use. */
+    private HttpParams http_params;
+
+    /** The background thread. */
+    private SimpleHttpDispatcherThread background_thread;
+
+
+    /** The monitor object for accessing the queue of request handles. */
+    protected final Object request_handle_monitor =
+        new String("SimpleHttpDispatcher.request_handle_monitor");
+
+    /**
+     * The queue of request handles to process.
+     * Request handles are handles for requests that have not been sent yet.
+     */
+    private final List request_handle_queue;
+
+    /** The monitor object for accessing the queue of response handles. */
+    protected final Object response_handle_monitor =
+        new String("SimpleHttpDispatcher.response_handle_monitor");
+
+    /**
+     * The collection of response handles.
+     * Response handles are handles for requests that have been sent
+     * or are being sent right now. Response handles are thrown away
+     * only after the connection over which the response is received
+     * is available again.
+     * For the simple dispatcher, there is at most one response handle.
+     */
+    private final Collection response_handles;
+  
+
+    /**
+     * Create a new simple HTTP dispatcher.
+     *
+     * @param conn      the connection to use
+     * @param proc      the HTTP processor to use,
+     *                  including the default context
+     * @param reuse     the strategy for re-using connections, or
+     *                  <code>null</code> to disable connection re-use
+     * @param params    the parameters to use
+     */
+    public SimpleHttpDispatcher(HttpClientConnection    conn,
+                                AsyncHttpProcessor      proc,
+                                ConnectionReuseStrategy reuse,
+                                HttpParams              params) {
+        super(null);
+
+        if (conn == null)
+            throw new IllegalArgumentException("connection must not be null");
+        if (proc == null)
+            throw new IllegalArgumentException("processor must not be null");
+        if (params == null)
+            throw new IllegalArgumentException("parameters must not be null");
+
+        client_connection = conn;
+        async_processor   = proc;
+        reuse_strategy    = reuse;
+        http_params       = params;
+
+        request_handle_queue = new LinkedList();
+        response_handles     = new LinkedList();
+
+        background_thread = new SimpleHttpDispatcherThread();
+        background_thread.setDaemon(true);
+        background_thread.start();
+
+    } // constructor
+
+
+
+    // non-javadoc, see interface HttpDispatcher
+    public HttpHandle sendRequest(HttpRequest request,
+                                  HttpHost target,
+                                  HttpContext context)
+        throws HttpException, IOException {
+
+        if (request == null)
+            throw new IllegalArgumentException("request must not be null");
+        if (target == null)
+            throw new IllegalArgumentException("target host must not be null");
+
+        if ((request instanceof HttpEntityEnclosingRequest) &&
+            ((HttpEntityEnclosingRequest)request).expectContinue()) {
+
+            throw new IllegalArgumentException
+                ("expect-continue not supported asynchronously");
+        }
+
+        //@@@ check whether target is suitable:
+        //@@@ - for now: no proxy (how to indicate proxy in the first place?)
+
+        HttpContext ctxt = prepareRequest
+            (async_processor, request, target, http_params, context);
+        SimpleHttpHandle hdl = new SimpleHttpHandle(this, request, ctxt);
+
+        // linked handles need to be tracked for abortAll()
+        synchronized (linked_handle_monitor) {
+            linked_handles.add(hdl);
+
+            // Queue the handle, it will be picked up by the background thread.
+            // Double-synchronized so abortAll() can't drop the handle from the
+            // linked_handles before we insert it into the the request queue.
+            synchronized (request_handle_monitor) {
+                request_handle_queue.add(hdl);
+                // tell the background thread
+                request_handle_monitor.notifyAll();
+            }
+        }
+
+
+        return hdl;
+
+    } // sendRequest
+
+
+    // non-javadoc, see base class AbstractHttpDispatcher
+    protected void postprocessResponse(AbstractHttpHandle handle,
+                                       HttpMutableResponse response)
+        throws HttpException, IOException {
+
+        if (handle == null)
+            throw new IllegalArgumentException("handle must not be null");
+        if (response == null)
+            throw new IllegalArgumentException("response must not be null");
+        handle.checkDispatcher(this);
+
+        finishResponse(async_processor, response, handle.getContext());
+
+    } // postprocessResponse
+
+
+
+    // non-javadoc, see interface HttpDispatcher
+    public final HttpContext getDefaultContext() {
+
+        return async_processor.getDefaultContext();
+    }
+
+
+    // non-javadoc, see base class AbstractHttpHandle
+    protected void closeHandle(AbstractHttpHandle handle, boolean abort)
+        throws HttpException, IOException {
+
+        if (handle == null)
+            throw new IllegalArgumentException("handle must not be null");
+        handle.checkDispatcher(this);
+
+        boolean found = false;
+        synchronized (linked_handle_monitor) {
+            found = linked_handles.remove(handle);
+        }
+        if (!found) {
+            // unlinked handles are no concern anymore
+            return;
+        }
+
+        // The handle might be in the request queue, the response collection,
+        // or neither. There is also a small window in which the handle is
+        // removed from the request queue by the background thread, but not
+        // yet put into the response collection. Let the background thread
+        // deal with that.
+
+        synchronized (request_handle_monitor) {
+            found = request_handle_queue.remove(handle);
+        }
+
+        if (!found) {
+            synchronized (response_handle_monitor) {
+                found = response_handles.remove(handle);
+                try {
+                    if (found) {
+                        boolean haveresponse =
+                            closeResponse((SimpleHttpHandle)handle, abort);
+                        if (abort && !haveresponse) {
+                            // it is probably waiting for the response:
+                            background_thread.interrupt();
+                        }
+                    }
+                } finally {
+                    response_handle_monitor.notifyAll();
+                }
+            } // synchronized response_handle_monitor
+        }
+
+    } // closeHandle
+
+
+    /**
+     * Close a response.
+     * This includes deciding an connection re-use and whether to
+     * close the connection or read to the end of the response entity.
+     * It does not include notification of the background thread.
+     *
+     * @param handle    the handle for which to close the response
+     * @param abort     <code>true</code> for a hard abort, or
+     *                  <code>false</code> for a smooth close
+     *
+     * @return  <code>true</code> if there is a response object,
+     *          <code>false</code> otherwise
+     *
+     * @throws IOException      in case of a problem closing the response
+     */
+    private final boolean closeResponse(SimpleHttpHandle handle, boolean abort)
+        throws IOException {
+
+        HttpResponse response = handle.internalGetResponse();
+        boolean      reuse    = false;
+        try {
+            if (!abort && (response != null) &&
+                (reuse_strategy != null) &&
+                reuse_strategy.keepAlive(response)) {
+
+                // consume rest of the entity, if there is one
+                HttpEntity entity = response.getEntity();
+                if (entity != null) {
+                    entity.consumeContent();
+                }
+                reuse = true;
+            }
+        } finally {
+            // This could trigger an exception during exception handling,
+            // but we need to close the connection if it can't be re-used.
+            if (!reuse)
+                client_connection.close();
+        }
+
+        return (response != null);
+
+    } // closeResponse
+
+
+    // non-javadoc, see interface HttpDispatcher
+    public void abortAll() {
+
+        // this will prevent interference from newly dispatcher requests
+        synchronized (linked_handle_monitor) {
+
+            // first, clear the request queue so handles can't be picked up
+            synchronized (request_handle_monitor) {
+                request_handle_queue.clear();
+            }
+
+            // Now abort each handle individually. This cleans up handles in
+            // the response collection and ensures application notification.
+            // Keep this in the synchronized block to make sure no new handles
+            // are created and possibly picked up until all current ones have
+            // been aborted. The collection is copied for stable iteration.
+
+            HttpHandle[] handles = (HttpHandle[])
+                linked_handles.toArray(new HttpHandle[linked_handles.size()]);
+
+            for (int i=0; i<handles.length; i++) {
+                if (handles[i] != null) // you never know
+                    handles[i].abort();
+            }
+        } // synchronized linked_handle_monitor
+
+    } // abortAll
+
+
+
+
+
+    /**
+     * Background thread for the simple dispatcher.
+     * This needs to be an inner class, since the monitors
+     * and handle queues should be private.
+     *
+     * @version $Revision$ $Date$
+     * 
+     * @since 4.0
+     */
+    private class SimpleHttpDispatcherThread extends Thread {
+
+        /**
+         * Main loop of this background dispatch thread.
+         * Waits for a request to dispatch, sends the request,
+         * waits and sets up the response, waits for completion of
+         * response processing, and starts again.
+         */
+        public void run() {
+
+            while (background_thread == this) {
+
+                SimpleHttpHandle handle = null;
+                try {
+                    handle = awaitRequestHandle();
+                    if (handle != null) {
+
+                        synchronized (response_handle_monitor) {
+                            // the check for stale handles must be performed
+                            // within this synchronized block, for proper
+                            // synchronization with closeHandle()
+                            if (!handle.isLinked())
+                                continue; // while (background_thread)
+
+                            response_handles.add(handle);
+                        }
+
+                        //@@@ TODO: retry handling!
+                        transmitRequest(async_processor,
+                                        handle.getRequest(),
+                                        handle.getContext(),
+                                        client_connection);
+
+                        //@@@ TODO: timeout handling!
+                        HttpMutableResponse response = 
+                            obtainResponse(async_processor,
+                                           handle.getRequest(),
+                                           client_connection);
+                        handle.provideResponse(response);
+
+                        if (response.getEntity() != null) {
+                            awaitCompletion(handle);
+                        } else {
+                            //@@@ close/unlink the handle?
+                        }
+
+                    } // if request handle
+
+                } catch (Throwable t) {
+                    cleanupOnProblem(handle, t);
+                }
+            } // while thread not cancelled
+
+        } // run
+
+
+        /**
+         * Clean up after a problem was encountered.
+         * The problem is indicated via the handle, if there is one.
+         * The connection is shut down to establish a defined state.
+         *
+         * @param handle    the handle for which there was a problem,
+         *                  or <code>null</code> if there is none
+         * @param dart      the exception indicating the problem
+         */
+        private void cleanupOnProblem(SimpleHttpHandle handle,
+                                      Throwable dart) {
+
+            //@@@ TODO: log the problem, in case it isn't picked up by the app
+
+            if (handle == null) {
+                // No handle means no request, and nothing can have been sent
+                // via the connection. No need to shut it down in this case.
+                return;
+            }
+
+            synchronized (response_handle_monitor) {
+                response_handles.remove(handle);
+            }
+            handle.provideProblem(dart);
+
+            try {
+                client_connection.shutdown();
+            } catch (IOException iox) {
+                //@@@ TODO: log the problem
+//System.out.println("@@@ exception shutting down connection");
+//iox.printStackTrace(System.out); //@@@
+            }
+
+        } // cleanupOnProblem
+
+
+        /**
+         * Wait for a request handle.
+         * That's a handle from the queue of requests that need to be sent.
+         *
+         * @return  the handle of the request to send, or
+         *          <code>null</code> if the thread has been cancelled
+         */
+        private SimpleHttpHandle awaitRequestHandle() {
+
+            SimpleHttpHandle handle = null;
+            synchronized (request_handle_monitor) {
+
+                while (request_handle_queue.isEmpty() &&
+                       (background_thread == this)) {
+
+                    try {
+                        request_handle_monitor.wait();
+
+                    } catch (InterruptedException ix) {
+                        // ignore and re-evaluate the while(...) condition
+                    }
+                } // while
+
+                if (!request_handle_queue.isEmpty())
+                    handle = (SimpleHttpHandle) request_handle_queue.remove(0);
+
+            } // synchronized
+
+            return handle;
+
+        } // awaitRequestHandle
+
+
+
+        /**
+         * Wait for a response handle to be closed.
+         * This indicates that the connection can be used for the next request.
+         *
+         * @return  the handle of the request to send, or
+         *          <code>null</code> if the thread has been cancelled
+         */
+        private void awaitCompletion(SimpleHttpHandle handle) {
+
+            synchronized (response_handle_monitor) {
+
+                while (response_handles.contains(handle) &&
+                       (background_thread == this)) {
+
+                    try {
+                        response_handle_monitor.wait();
+
+                    } catch (InterruptedException ix) {
+                        // ignore and re-evaluate the while(...) condition
+                    }
+                } // while
+            } // synchronized response_handle_monitor
+
+        } // awaitCompletion
+
+    } // class SimpleHttpDispatcherThread
+
+
+    /**
+     * Create a human-readable description of this object.
+     * Used for debug output.
+     *
+     * @return  string description of this object
+     */
+    public String toString() {
+
+        StringBuffer sb = new StringBuffer(super.toString());
+
+        synchronized (linked_handle_monitor) {
+            synchronized (request_handle_monitor) {
+                synchronized (response_handle_monitor) {
+                    sb.append("\nlinked handles: ")
+                        .append(linked_handles)
+                        .append("\nrequest handles: ")
+                        .append(request_handle_queue)
+                        .append("\nresponse handles: ")
+                        .append(response_handles);
+                }
+            }
+        }
+
+        return sb.toString();
+
+    } // toString
+
+
+} // class SimpleHttpDispatcher

Propchange: jakarta/httpcomponents/trunk/http-async/src/java/org/apache/http/async/impl/SimpleHttpDispatcher.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jakarta/httpcomponents/trunk/http-async/src/java/org/apache/http/async/impl/SimpleHttpDispatcher.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: jakarta/httpcomponents/trunk/http-async/src/java/org/apache/http/async/impl/SimpleHttpDispatcher.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: jakarta/httpcomponents/trunk/http-async/src/java/org/apache/http/async/impl/SimpleHttpHandle.java
URL: http://svn.apache.org/viewcvs/jakarta/httpcomponents/trunk/http-async/src/java/org/apache/http/async/impl/SimpleHttpHandle.java?rev=375356&view=auto
==============================================================================
--- jakarta/httpcomponents/trunk/http-async/src/java/org/apache/http/async/impl/SimpleHttpHandle.java (added)
+++ jakarta/httpcomponents/trunk/http-async/src/java/org/apache/http/async/impl/SimpleHttpHandle.java Mon Feb  6 12:29:56 2006
@@ -0,0 +1,255 @@
+/*
+ * $HeadURL$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ *
+ *  Copyright 2006 The Apache Software Foundation
+ *
+ *  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.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+
+package org.apache.http.async.impl;
+
+
+import java.io.IOException;
+
+import org.apache.http.HttpRequest;
+import org.apache.http.HttpResponse;
+import org.apache.http.HttpMutableResponse;
+import org.apache.http.HttpHost;
+import org.apache.http.HttpException;
+import org.apache.http.protocol.HttpContext;
+import org.apache.http.async.HttpDispatcher;
+import org.apache.http.async.AbstractHttpHandle;
+
+
+
+/**
+ * Handles for the {@link SimpleHttpDispatcher SimpleHttpDispatcher}.
+ *
+ * @version $Revision$ $Date$
+ * 
+ * @since 4.0
+ */
+public class SimpleHttpHandle extends AbstractHttpHandle {
+    // Public and non-final because SimpleHttpDispatcher is not final.
+    // Derived dispatchers may have to instantiate or derive the handle class.
+
+
+    // a selection of possible response states
+    protected final static int RESPONSE_STATE_MISSING  = 0; // not received yet
+    protected final static int RESPONSE_STATE_PRESENT  = 1; // just received
+    protected final static int RESPONSE_STATE_FINISHED = 2; // post-processed
+
+
+    /** The response. It may or may not be postprocessed. */
+    HttpMutableResponse response_object;
+
+    /** The state of the response. */
+    private int response_state;
+
+    /** The monitor for synchronizing access to the response. */
+    private final Object response_monitor =
+    new String("SimpleHttpHandle.response_monitor");
+
+
+    /**
+     * Create a new handle.
+     *
+     * @param dispatcher  the dispatcher creating this handle
+     * @param request     the request to be handled
+     * @param context     the context for executing the request
+     */
+    /*default*/ SimpleHttpHandle(SimpleHttpDispatcher dispatcher,
+                                 HttpRequest request,
+                                 HttpContext context) {
+
+        super(dispatcher, request, context);
+
+        if (dispatcher == null)
+            throw new IllegalArgumentException("dispatcher must be specified");
+
+        // no need to synchronize in constructor
+        response_state = RESPONSE_STATE_MISSING;
+
+    } // constructor
+
+
+
+    // non-javadoc, see interface HttpHandle
+    public final HttpResponse getResponse() {
+
+        // if the response is pending post-processing,
+        // use the calling thread to do it now
+        synchronized (response_monitor) {
+            try {
+                if (response_state == RESPONSE_STATE_PRESENT)
+                    postprocessResponse();
+
+            } catch (Throwable t) {
+                response_object = null;
+                provideProblem(t);
+            }
+        } // synchronized response_monitor
+
+        return response_object;
+
+    } // getResponse
+
+
+    // non-javadoc, see interface HttpHandle
+    public final HttpResponse awaitResponse()
+        throws HttpException, IOException, InterruptedException {
+
+        synchronized (response_monitor) {
+            while (response_state == RESPONSE_STATE_MISSING) {
+                response_monitor.wait();
+            }
+            // use calling thread to perform post-processing
+            getResponse();
+        }
+
+        return response_object;
+
+    } // awaitResponse
+
+
+    /**
+     * Obtain the response object, if available.
+     * For use by the {@link SimpleHttpDispatcher dispatcher} only.
+     * This method does not synchronize the access, nor check a state,
+     * nor perform postprocessing.
+     *
+     * @return  the response object, or <code>null</code> if not available
+     */
+    protected final HttpResponse internalGetResponse() {
+
+        return response_object;
+    }
+
+
+    // non-javadoc, see interface HttpHandle
+    public synchronized void close()
+        throws HttpException, IOException {
+
+        setLinked(false);
+        dispatcherCloseHandle(false);
+
+        synchronized (response_monitor) {
+            // handle remains useable if there is a response
+            if (response_state == RESPONSE_STATE_MISSING) {
+                provideProblem(new IllegalStateException("closed"));
+            }
+        }
+
+    } // close
+
+
+    // non-javadoc, see interface HttpHandle
+    public void abort() {
+
+        setLinked(false);
+        try {
+            dispatcherCloseHandle(true);
+        } catch (Exception x) {
+            // ignore: sanity checks will be passed, nothing else is expected
+            // to fail, caller is not interested in handling problems anyway
+        }
+
+        synchronized (response_monitor) {
+            // handle no longer useable
+            response_object = null;
+            provideProblem(new IllegalStateException("aborted"));
+        }
+
+    } // abort
+
+
+    /**
+     * Provide the response for this handle.
+     * This method is called by the background thread of the
+     * {@link SimpleHttpDispatcher SimpleHttpDispatcher}.
+     *
+     * @param response    the response, received but not post-processed
+     */
+    public final void provideResponse(HttpMutableResponse response) {
+
+        synchronized (response_monitor) {
+            response_object = response;
+            response_state = RESPONSE_STATE_PRESENT;
+            response_monitor.notifyAll();
+        }
+
+    } // provideResponse
+
+
+    /**
+     * Provide the problem for this handle.
+     * A problem means there will be no {@link #provideResponse response}.
+     * This method is called by the background thread of the
+     * {@link SimpleHttpDispatcher SimpleHttpDispatcher}.
+     *
+     * @param dart        the exception indicating the problem,
+     *                    or <code>null</code> to indicate an unknown problem
+     */
+    public final void provideProblem(Throwable dart) {
+
+        // don't throw an exception during exception handling!
+        if (dart == null)
+            dart = new HttpException("problem without exception");
+
+        setError(dart);
+        synchronized (response_monitor) {
+            response_state = RESPONSE_STATE_FINISHED;
+            response_monitor.notifyAll();
+        }
+
+    } // provideProblem
+
+
+    /**
+     * Post-process the response.
+     * This will update the response object and state.
+     *
+     * @throws HttpException      in case of a problem
+     * @throws IOException        in case of an IO problem
+     */
+    private final void postprocessResponse()
+        throws HttpException, IOException {
+
+        synchronized (response_monitor) {
+
+            if (response_state != RESPONSE_STATE_PRESENT) {
+                return; // Ha ha, very funny. Duh!
+            }
+
+            if (response_object != null)
+                dispatcherPostprocess(response_object);
+
+            response_state = RESPONSE_STATE_FINISHED;
+
+        } // synchronized response_monitor
+
+    } // postprocessResponse
+
+
+} // class SimpleHttpHandle

Propchange: jakarta/httpcomponents/trunk/http-async/src/java/org/apache/http/async/impl/SimpleHttpHandle.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jakarta/httpcomponents/trunk/http-async/src/java/org/apache/http/async/impl/SimpleHttpHandle.java
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: jakarta/httpcomponents/trunk/http-async/src/java/org/apache/http/async/impl/SimpleHttpHandle.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Added: jakarta/httpcomponents/trunk/http-async/src/java/org/apache/http/async/impl/package.html
URL: http://svn.apache.org/viewcvs/jakarta/httpcomponents/trunk/http-async/src/java/org/apache/http/async/impl/package.html?rev=375356&view=auto
==============================================================================
--- jakarta/httpcomponents/trunk/http-async/src/java/org/apache/http/async/impl/package.html (added)
+++ jakarta/httpcomponents/trunk/http-async/src/java/org/apache/http/async/impl/package.html Mon Feb  6 12:29:56 2006
@@ -0,0 +1,37 @@
+<html>
+<head>
+<!--
+/*
+ * $HeadURL$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ *
+ *  Copyright 2006 The Apache Software Foundation
+ *
+ *  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.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+-->
+</head>
+<body>
+Implementation of asynchronous HTTP communication.
+</body>
+</html>

Propchange: jakarta/httpcomponents/trunk/http-async/src/java/org/apache/http/async/impl/package.html
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jakarta/httpcomponents/trunk/http-async/src/java/org/apache/http/async/impl/package.html
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: jakarta/httpcomponents/trunk/http-async/src/java/org/apache/http/async/impl/package.html
------------------------------------------------------------------------------
    svn:mime-type = text/html

Added: jakarta/httpcomponents/trunk/http-async/src/java/org/apache/http/async/package.html
URL: http://svn.apache.org/viewcvs/jakarta/httpcomponents/trunk/http-async/src/java/org/apache/http/async/package.html?rev=375356&view=auto
==============================================================================
--- jakarta/httpcomponents/trunk/http-async/src/java/org/apache/http/async/package.html (added)
+++ jakarta/httpcomponents/trunk/http-async/src/java/org/apache/http/async/package.html Mon Feb  6 12:29:56 2006
@@ -0,0 +1,37 @@
+<html>
+<head>
+<!--
+/*
+ * $HeadURL$
+ * $Revision$
+ * $Date$
+ *
+ * ====================================================================
+ *
+ *  Copyright 2006 The Apache Software Foundation
+ *
+ *  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.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */
+-->
+</head>
+<body>
+API for sending HTTP requests asynchronously.
+</body>
+</html>

Propchange: jakarta/httpcomponents/trunk/http-async/src/java/org/apache/http/async/package.html
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: jakarta/httpcomponents/trunk/http-async/src/java/org/apache/http/async/package.html
------------------------------------------------------------------------------
    svn:keywords = Date Author Id Revision HeadURL

Propchange: jakarta/httpcomponents/trunk/http-async/src/java/org/apache/http/async/package.html
------------------------------------------------------------------------------
    svn:mime-type = text/html