1
2
3
4
5
6
7
8 package org.codehaus.spice.netserve.connection.impl;
9
10 import java.io.IOException;
11 import java.io.InterruptedIOException;
12 import java.net.Socket;
13
14 import org.codehaus.spice.netserve.connection.impl.AcceptorConfig;
15 import org.codehaus.spice.netserve.connection.impl.AcceptorMonitor;
16
17 /***
18 * A helper class that manages acceptor for a single ServerSocket.
19 *
20 * @author Peter Donald
21 * @version $Revision: 1.2 $ $Date: 2004/03/21 23:42:59 $
22 */
23 class ConnectionAcceptor
24 implements Runnable
25 {
26 /***
27 * The configuration for acceptor.
28 */
29 private final AcceptorConfig m_config;
30
31 /***
32 * The AcceptorMonitor for event notification.
33 */
34 private final AcceptorMonitor m_monitor;
35
36 private boolean m_started;
37
38 private boolean m_active;
39
40 /***
41 * The thread in which the main accept loop is running.
42 * Setup at start of thread and set to null to shutdown
43 * acceptor.
44 */
45 private Thread m_thread;
46
47 /***
48 * Create the acceptor.
49 *
50 * @param config the config for acceptor
51 * @param monitor the monitor
52 */
53 ConnectionAcceptor( final AcceptorConfig config,
54 final AcceptorMonitor monitor )
55 {
56 if( null == config )
57 {
58 throw new NullPointerException( "config" );
59 }
60 if( null == monitor )
61 {
62 throw new NullPointerException( "monitor" );
63 }
64 m_config = config;
65 m_monitor = monitor;
66 m_monitor.acceptorCreated( m_config.getName(),
67 m_config.getServerSocket() );
68 }
69
70 /***
71 * Return true if acceptor has started.
72 *
73 * @return true if acceptor has started.
74 */
75 synchronized boolean hasStarted()
76 {
77 return m_started;
78 }
79
80 /***
81 * Shutdown the acceptor.
82 */
83 void close( final long timeout )
84 {
85 synchronized( this )
86 {
87 m_active = false;
88 m_monitor.acceptorClosing( m_config.getName(),
89 m_config.getServerSocket() );
90 m_thread.interrupt();
91 try
92 {
93 wait( timeout );
94 }
95 catch( InterruptedException e )
96 {
97
98 }
99 }
100 }
101
102 /***
103 * The main accept & handle loop for acceptor.
104 */
105 public void run()
106 {
107
108 synchronized( this )
109 {
110 m_started = true;
111 m_active = true;
112 m_thread = Thread.currentThread();
113 }
114 while( isRunning() )
115 {
116 m_monitor.serverSocketListening( m_config.getName(),
117 m_config.getServerSocket() );
118 try
119 {
120 final Socket socket = m_config.getServerSocket().accept();
121 if( isRunning() )
122 {
123 m_config.getHandler().handleConnection( socket );
124 }
125 else
126 {
127 try
128 {
129 socket.close();
130 }
131 catch( final Exception e )
132 {
133
134 }
135 }
136 }
137 catch( final InterruptedIOException iioe )
138 {
139
140 }
141 catch( final IOException ioe )
142 {
143 m_monitor.errorAcceptingConnection( m_config.getName(), ioe );
144 }
145 }
146
147 shutdownServerSocket();
148 synchronized( this )
149 {
150 m_thread = null;
151 notifyAll();
152 }
153 }
154
155 /***
156 * Utility method to shutdown serverSocket.
157 */
158 void shutdownServerSocket()
159 {
160 try
161 {
162 m_config.getServerSocket().close();
163 }
164 catch( final IOException ioe )
165 {
166 m_monitor.errorClosingServerSocket( m_config.getName(), ioe );
167 }
168 }
169
170 /***
171 * Return true if the acceptor is currently running.
172 *
173 * @return true if the acceptor is currently running.
174 */
175 synchronized boolean isRunning()
176 {
177 return m_active;
178 }
179 }