Skip to content

Commit 5188097

Browse files
committed
fix: Does not close Multiplexing on Multiplexed.close()
Waits until all of the Multiplexed sockets belonging to a Multiplexing are closed before closing the Multiplexing socket. Also introduces the "persistent" flag of Multiplexing, which keeps it open even after all of its Multiplexed sockets are closed. fix: Makes MultiplexingDatagramSocket#persistent final.
1 parent f6e3deb commit 5188097

File tree

3 files changed

+140
-5
lines changed

3 files changed

+140
-5
lines changed

src/main/java/org/ice4j/socket/MultiplexedDatagramSocket.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,10 @@ public void close()
119119
{
120120
multiplexing.close(this);
121121

122-
super.close();
122+
// We intentionally do not call super.close(), because it eventually
123+
// delegates to #multiplexing. We don't want to close #multiplexing
124+
// just yet, because it may have other filtered sockets attached to it
125+
// (or it needs to be kept open for other reasons)
123126
}
124127

125128
/**

src/main/java/org/ice4j/socket/MultiplexingDatagramSocket.java

Lines changed: 132 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -99,8 +99,9 @@ protected List<DatagramPacket> getReceived(
9999

100100
/**
101101
* The list of <tt>DatagramPacket</tt>s to be received through this
102-
* <tt>DatagramSocket</tt> i.e. not accepted by the <tt>DatagramFilter</tt>s
103-
* of {@link #sockets} at the time of the reading from the network.
102+
* <tt>DatagramSocket</tt> i.e. not accepted by the list of
103+
* {@link MultiplexedDatagramSocket} of this instance at the time of the
104+
* reading from the network.
104105
*/
105106
private final List<DatagramPacket> received
106107
= new SocketReceiveBuffer()
@@ -125,6 +126,15 @@ public int getReceiveBufferSize()
125126
*/
126127
private int soTimeout = 0;
127128

129+
/**
130+
* Whether this socket should be kept open even when all of its
131+
* {@link MultiplexedDatagramSocket} are closed (if the value is
132+
* {@code true}), or it should be closed when the last of its
133+
* {@link MultiplexedDatagramSocket} is closed (if the value is
134+
* {@code false}).
135+
*/
136+
private final boolean persistent;
137+
128138
/**
129139
* Initializes a new <tt>MultiplexingDatagramSocket</tt> instance which is
130140
* to enable <tt>DatagramPacket</tt> filtering and binds it to any available
@@ -138,6 +148,25 @@ public int getReceiveBufferSize()
138148
public MultiplexingDatagramSocket()
139149
throws SocketException
140150
{
151+
this(false);
152+
}
153+
154+
/**
155+
* Initializes a new <tt>MultiplexingDatagramSocket</tt> instance which is
156+
* to enable <tt>DatagramPacket</tt> filtering and binds it to any available
157+
* port on the local host machine. The socket will be bound to the wildcard
158+
* address, an IP address chosen by the kernel.
159+
*
160+
* @throws SocketException if the socket could not be opened, or the socket
161+
* could not bind to the specified local port
162+
* @param persistent whether this socket should be kept open after all of
163+
* its {@link MultiplexedDatagramSocket}s are closed.
164+
* @see DatagramSocket#DatagramSocket()
165+
*/
166+
public MultiplexingDatagramSocket(boolean persistent)
167+
throws SocketException
168+
{
169+
this.persistent = persistent;
141170
}
142171

143172
/**
@@ -152,8 +181,30 @@ public MultiplexingDatagramSocket()
152181
*/
153182
public MultiplexingDatagramSocket(DatagramSocket delegate)
154183
throws SocketException
184+
{
185+
this(delegate, false);
186+
}
187+
188+
/**
189+
* Initializes a new <tt>MultiplexingDatagramSocket</tt> instance which is
190+
* to enable <tt>DatagramPacket</tt> filtering on a specific
191+
* <tt>DatagramSocket</tt>.
192+
*
193+
* @param delegate the <tt>DatagramSocket</tt> on which
194+
* <tt>DatagramPacket</tt> filtering is to be enabled by the new instance
195+
* @param persistent whether this socket should be kept open after all of
196+
* its {@link MultiplexedDatagramSocket}s are closed.
197+
* @throws SocketException if anything goes wrong while initializing the new
198+
* instance
199+
*/
200+
public MultiplexingDatagramSocket(
201+
DatagramSocket delegate,
202+
boolean persistent)
203+
throws SocketException
155204
{
156205
super(delegate);
206+
207+
this.persistent = persistent;
157208
}
158209

159210
/**
@@ -169,8 +220,29 @@ public MultiplexingDatagramSocket(DatagramSocket delegate)
169220
*/
170221
public MultiplexingDatagramSocket(int port)
171222
throws SocketException
223+
{
224+
this(port, false);
225+
}
226+
227+
/**
228+
* Initializes a new <tt>MultiplexingDatagramSocket</tt> instance which is
229+
* to enable <tt>DatagramPacket</tt> filtering and binds it to the specified
230+
* port on the local host machine. The socket will be bound to the wildcard
231+
* address, an IP address chosen by the kernel.
232+
*
233+
* @param port the port to bind the new socket to
234+
* @param persistent whether this socket should be kept open after all of
235+
* its {@link MultiplexedDatagramSocket}s are closed.
236+
* @throws SocketException if the socket could not be opened, or the socket
237+
* could not bind to the specified local port
238+
* @see DatagramSocket#DatagramSocket(int)
239+
*/
240+
public MultiplexingDatagramSocket(int port, boolean persistent)
241+
throws SocketException
172242
{
173243
super(port);
244+
245+
this.persistent = persistent;
174246
}
175247

176248
/**
@@ -188,8 +260,34 @@ public MultiplexingDatagramSocket(int port)
188260
*/
189261
public MultiplexingDatagramSocket(int port, InetAddress laddr)
190262
throws SocketException
263+
{
264+
this(port, laddr, false);
265+
}
266+
267+
/**
268+
* Initializes a new <tt>MultiplexingDatagramSocket</tt> instance which is
269+
* to enable <tt>DatagramPacket</tt> filtering, bound to the specified local
270+
* address. The local port must be between 0 and 65535 inclusive. If the IP
271+
* address is 0.0.0.0, the socket will be bound to the wildcard address, an
272+
* IP address chosen by the kernel.
273+
*
274+
* @param port the local port to bind the new socket to
275+
* @param laddr the local address to bind the new socket to
276+
* @param persistent whether this socket should be kept open after all of
277+
* its {@link MultiplexedDatagramSocket}s are closed.
278+
* @throws SocketException if the socket could not be opened, or the socket
279+
* could not bind to the specified local port
280+
* @see DatagramSocket#DatagramSocket(int, InetAddress)
281+
*/
282+
public MultiplexingDatagramSocket(
283+
int port,
284+
InetAddress laddr,
285+
boolean persistent)
286+
throws SocketException
191287
{
192288
super(port, laddr);
289+
290+
this.persistent = persistent;
193291
}
194292

195293
/**
@@ -209,8 +307,35 @@ public MultiplexingDatagramSocket(int port, InetAddress laddr)
209307
*/
210308
public MultiplexingDatagramSocket(SocketAddress bindaddr)
211309
throws SocketException
310+
{
311+
this(bindaddr, false);
312+
}
313+
314+
/**
315+
* Initializes a new <tt>MultiplexingDatagramSocket</tt> instance which is
316+
* to enable <tt>DatagramPacket</tt> filtering, bound to the specified local
317+
* socket address.
318+
* <p>
319+
* If the specified local socket address is <tt>null</tt>, creates an
320+
* unbound socket.
321+
* </p>
322+
*
323+
* @param bindaddr local socket address to bind, or <tt>null</tt> for an
324+
* unbound socket
325+
* @param persistent whether this socket should be kept open after all of
326+
* its {@link MultiplexedDatagramSocket}s are closed.
327+
* @throws SocketException if the socket could not be opened, or the socket
328+
* could not bind to the specified local port
329+
* @see DatagramSocket#DatagramSocket(SocketAddress)
330+
*/
331+
public MultiplexingDatagramSocket(
332+
SocketAddress bindaddr,
333+
boolean persistent)
334+
throws SocketException
212335
{
213336
super(bindaddr);
337+
338+
this.persistent = persistent;
214339
}
215340

216341
/**
@@ -221,7 +346,11 @@ public MultiplexingDatagramSocket(SocketAddress bindaddr)
221346
*/
222347
void close(MultiplexedDatagramSocket multiplexed)
223348
{
224-
multiplexingXXXSocketSupport.close(multiplexed);
349+
if (!multiplexingXXXSocketSupport.close(multiplexed)
350+
&& !persistent)
351+
{
352+
close();
353+
}
225354
}
226355

227356
/**

src/main/java/org/ice4j/socket/MultiplexingXXXSocketSupport.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -279,12 +279,15 @@ private void acceptBySocketsOrThis(DatagramPacket p)
279279
* <tt>DatagramPacket</tt>s away from this <tt>DatagramSocket</tt>.
280280
*
281281
* @param multiplexed the <tt>MultiplexedDatagramSocket</tt> to close
282+
* @return {@code true} if there are remaining filtered sockets.
282283
*/
283-
void close(MultiplexedXXXSocketT multiplexed)
284+
boolean close(MultiplexedXXXSocketT multiplexed)
284285
{
285286
synchronized (sockets)
286287
{
287288
sockets.remove(multiplexed);
289+
290+
return !sockets.isEmpty();
288291
}
289292
}
290293

0 commit comments

Comments
 (0)