1
2
3
4
5
6
7
8 package org.codehaus.spice.netserve.connection.handlers;
9
10 import java.net.Socket;
11 import java.util.Map;
12 import java.util.Hashtable;
13 import java.util.Collection;
14 import org.codehaus.spice.netserve.connection.RequestHandler;
15 import org.codehaus.spice.threadpool.ThreadPool;
16 import org.codehaus.spice.threadpool.ThreadControl;
17
18 /***
19 * A Handler that uses a thread from a pool for each different request.
20 *
21 * @author Peter Donald
22 * @version $Revision: 1.2 $ $Date: 2004/03/21 23:42:58 $
23 */
24 public class ThreadPerRequestHandler
25 extends DelegatingRequestHandler
26 {
27 /***
28 * A map of Socket->ThreadControl.
29 */
30 private final Map m_controlMap = new Hashtable();
31
32 /***
33 * the thread pool that used to handle requests.
34 */
35 private final ThreadPool m_threadPool;
36
37 /***
38 * Create handler.
39 *
40 * @param handler the underlying handler
41 * @param threadPool the thread pool to use to create handler threads
42 */
43 public ThreadPerRequestHandler( final RequestHandler handler,
44 final ThreadPool threadPool )
45 {
46 super( handler );
47 if( null == threadPool )
48 {
49 throw new NullPointerException( "threadPool" );
50 }
51 m_threadPool = threadPool;
52 }
53
54 /***
55 * Execute each request in a separate thread.
56 *
57 * @param socket the socket to handle
58 */
59 public void handleConnection( final Socket socket )
60 {
61 final Runnable runnable = createRunnable( socket );
62 final ThreadControl control = m_threadPool.execute( runnable );
63 m_controlMap.put( socket, control );
64 }
65
66 /***
67 * Remove ThreadControl from list of active threads.
68 *
69 * @param socket the socket
70 */
71 protected void endConnection( Socket socket )
72 {
73 m_controlMap.remove( socket );
74 super.endConnection( socket );
75 }
76
77 /***
78 * Shutdown all requests including those executing in thread pool.
79 *
80 * @param timeout the timeout
81 */
82 public void shutdown( final long timeout )
83 {
84 markAsShutdown();
85 final ThreadControl[] controls;
86 synchronized( m_controlMap )
87 {
88 final Collection collection = m_controlMap.values();
89 controls = (ThreadControl[])collection.
90 toArray( new ThreadControl[ collection.size() ] );
91 }
92 for( int i = 0; i < controls.length; i++ )
93 {
94 final ThreadControl control = controls[ i ];
95 if( !control.isFinished() )
96 {
97 control.interrupt();
98 }
99 }
100 super.shutdown( timeout );
101 for( int i = 0; i < controls.length; i++ )
102 {
103 final ThreadControl control = controls[ i ];
104 if( !control.isFinished() )
105 {
106 try
107 {
108 control.join( timeout );
109 }
110 catch( final InterruptedException ie )
111 {
112
113 }
114 }
115 }
116 }
117 }