1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 *
19 */
20 package org.apache.mina.transport.socket.apr;
21
22 import java.net.InetSocketAddress;
23
24 import org.apache.mina.core.filterchain.DefaultIoFilterChain;
25 import org.apache.mina.core.filterchain.IoFilterChain;
26 import org.apache.mina.core.service.IoHandler;
27 import org.apache.mina.core.service.IoProcessor;
28 import org.apache.mina.core.service.IoService;
29 import org.apache.mina.core.session.AbstractIoSession;
30 import org.apache.mina.core.session.IoSession;
31 import org.apache.tomcat.jni.Address;
32 import org.apache.tomcat.jni.Socket;
33
34 /**
35 * An abstract {@link IoSession} serving of base for APR based sessions.
36 *
37 * @author <a href="http://mina.apache.org">Apache MINA Project</a>
38 */
39 public abstract class AprSession extends AbstractIoSession {
40
41 // good old socket descriptor
42 private long descriptor;
43
44 // the service handling this session
45 private final IoService service;
46
47 // the processor processing this session
48 private final IoProcessor<AprSession> processor;
49
50 // the mandatory filter chain of this session
51 private final IoFilterChain filterChain = new DefaultIoFilterChain(this);
52
53 // handler listeneing this session event
54 private final IoHandler handler;
55
56 // the two endpoint addresses
57 private final InetSocketAddress remoteAddress;
58 private final InetSocketAddress localAddress;
59
60 // current polling results
61 private boolean readable = true;
62 private boolean writable = true;
63 private boolean interestedInRead;
64 private boolean interestedInWrite;
65
66 /**
67 * Creates a new instance of {@link AprSession}. Need to be called by extending types
68 * @param service the {@link IoService} creating this session. Can be {@link AprSocketAcceptor} or
69 * {@link AprSocketConnector}
70 * @param processor the {@link AprIoProcessor} managing this session.
71 * @param descriptor the low level APR socket descriptor for this socket. {@see Socket#create(int, int, int, long)}
72 * @throws Exception exception produced during the setting of all the socket parameters.
73 */
74 AprSession(
75 IoService service, IoProcessor<AprSession> processor, long descriptor) throws Exception {
76 this.service = service;
77 this.processor = processor;
78 this.handler = service.getHandler();
79 this.descriptor = descriptor;
80
81 long ra = Address.get(Socket.APR_REMOTE, descriptor);
82 long la = Address.get(Socket.APR_LOCAL, descriptor);
83
84 this.remoteAddress = new InetSocketAddress(Address.getip(ra), Address.getInfo(ra).port);
85 this.localAddress = new InetSocketAddress(Address.getip(la), Address.getInfo(la).port);
86 }
87
88 /**
89 * Creates a new instance of {@link AprSession}. Need to be called by extending types.
90 * The constructor add remote address for UDP based sessions.
91 * @param service the {@link IoService} creating this session. Can be {@link AprSocketAcceptor} or
92 * {@link AprSocketConnector}
93 * @param processor the {@link AprIoProcessor} managing this session.
94 * @param descriptor the low level APR socket descriptor for this socket. {@see Socket#create(int, int, int, long)}
95 * @param remoteAddress the remote end-point
96 * @throws Exception exception produced during the setting of all the socket parameters.
97 */
98 AprSession(
99 IoService service, IoProcessor<AprSession> processor,
100 long descriptor, InetSocketAddress remoteAddress) throws Exception {
101 this.service = service;
102 this.processor = processor;
103 this.handler = service.getHandler();
104 this.descriptor = descriptor;
105
106 long la = Address.get(Socket.APR_LOCAL, descriptor);
107
108 this.remoteAddress = remoteAddress;
109 this.localAddress = new InetSocketAddress(Address.getip(la), Address.getInfo(la).port);
110 }
111
112 /**
113 * Get the socket descriptor {@see Socket#create(int, int, int, long)}.
114 * @return the low level APR socket descriptor
115 */
116 long getDescriptor() {
117 return descriptor;
118 }
119
120 /**
121 * Set the socket descriptor.
122 * @param desc the low level APR socket descriptor created by {@see Socket#create(int, int, int, long)}
123 */
124 void setDescriptor(long desc) {
125 this.descriptor = desc;
126 }
127
128 /**
129 * {@inheritDoc}
130 */
131 @Override
132 public IoProcessor<AprSession> getProcessor() {
133 return processor;
134 }
135
136 /**
137 * {@inheritDoc}
138 */
139 public InetSocketAddress getLocalAddress() {
140 return localAddress;
141 }
142
143 /**
144 * {@inheritDoc}
145 */
146 public InetSocketAddress getRemoteAddress() {
147 return remoteAddress;
148 }
149
150 /**
151 * {@inheritDoc}
152 */
153 public IoFilterChain getFilterChain() {
154 return filterChain;
155 }
156
157 /**
158 * {@inheritDoc}
159 */
160 public IoHandler getHandler() {
161 return handler;
162 }
163
164 /**
165 * {@inheritDoc}
166 */
167 public IoService getService() {
168 return service;
169 }
170
171 /**
172 * {@inheritDoc}
173 */
174 @Override
175 public InetSocketAddress getServiceAddress() {
176 return (InetSocketAddress) super.getServiceAddress();
177 }
178
179 /**
180 * Is this session was tagged are readable after a call to {@link Socket#pool(long)}.
181 * @return true if this session is ready for read operations
182 */
183 boolean isReadable() {
184 return readable;
185 }
186
187 /**
188 * Set if this session is readable after a call to {@link Socket#pool(long)}.
189 * @param readable true for set this session ready for read operations
190 */
191 void setReadable(boolean readable) {
192 this.readable = readable;
193 }
194
195 /**
196 * Is this session is tagged writable after a call to {@link Socket#pool(long)}.
197 * @return true if this session is ready for write operations
198 */
199 boolean isWritable() {
200 return writable;
201 }
202
203 /**
204 * Set if this session is writable after a call to {@link Socket#pool(long)}.
205 * @param writable true for set this session ready for write operations
206 */
207 void setWritable(boolean writable) {
208 this.writable = writable;
209 }
210
211 /**
212 * Does this session needs to be registered for read events.
213 * Used for building poll set {@see Poll}.
214 * @return true if registered
215 */
216 boolean isInterestedInRead() {
217 return interestedInRead;
218 }
219
220 /**
221 * Set if this session needs to be registered for read events.
222 * Used for building poll set {@see Poll}.
223 * @param isOpRead true if need to be registered
224 */
225 void setInterestedInRead(boolean isOpRead) {
226 this.interestedInRead = isOpRead;
227 }
228
229 /**
230 * Does this session needs to be registered for write events.
231 * Used for building poll set {@see Poll}.
232 * @return true if registered
233 */
234 boolean isInterestedInWrite() {
235 return interestedInWrite;
236 }
237
238 /**
239 * Set if this session needs to be registered for write events.
240 * Used for building poll set {@see Poll}.
241 * @param isOpWrite true if need to be registered
242 */
243 void setInterestedInWrite(boolean isOpWrite) {
244 this.interestedInWrite = isOpWrite;
245 }
246 }