1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266
/* * @(#)SelectorProvider.java 1.28 06/06/28 * * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms. */ package java.nio.channels.spi; import java.io.FileDescriptor; import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; import java.nio.channels.*; import java.security.AccessController; import java.security.PrivilegedAction; import java.util.Iterator; import sun.misc.Service; import sun.misc.ServiceConfigurationError; import sun.security.action.GetPropertyAction; /** * Service-provider class for selectors and selectable channels. * * <p> A selector provider is a concrete subclass of this class that has a * zero-argument constructor and implements the abstract methods specified * below. A given invocation of the Java virtual machine maintains a single * system-wide default provider instance, which is returned by the {@link * #provider() provider} method. The first invocation of that method will locate * the default provider as specified below. * * <p> The system-wide default provider is used by the static <tt>open</tt> * methods of the {@link java.nio.channels.DatagramChannel#open * DatagramChannel}, {@link java.nio.channels.Pipe#open Pipe}, {@link * java.nio.channels.Selector#open Selector}, {@link * java.nio.channels.ServerSocketChannel#open ServerSocketChannel}, and {@link * java.nio.channels.SocketChannel#open SocketChannel} classes. It is also * used by the {@link java.lang.System#inheritedChannel System.inheritedChannel()} * method. A program may make use of a provider other than the default provider * by instantiating that provider and then directly invoking the <tt>open</tt> * methods defined in this class. * * <p> All of the methods in this class are safe for use by multiple concurrent * threads. </p> * * * @author Mark Reinhold * @author JSR-51 Expert Group * @version 1.28, 06/06/28 * @since 1.4 */ public abstract class SelectorProvider { private static final Object lock = new Object(); private static SelectorProvider provider = null; /** * Initializes a new instance of this class. </p> * * @throws SecurityException * If a security manager has been installed and it denies * {@link RuntimePermission}<tt>("selectorProvider")</tt> */ protected SelectorProvider() { SecurityManager sm = System.getSecurityManager(); if (sm != null) sm.checkPermission(new RuntimePermission("selectorProvider")); } private static boolean loadProviderFromProperty() { String cn = System.getProperty("java.nio.channels.spi.SelectorProvider"); if (cn == null) return false; try { Class c = Class.forName(cn, true, ClassLoader.getSystemClassLoader()); provider = (SelectorProvider)c.newInstance(); return true; } catch (ClassNotFoundException x) { throw new ServiceConfigurationError(x); } catch (IllegalAccessException x) { throw new ServiceConfigurationError(x); } catch (InstantiationException x) { throw new ServiceConfigurationError(x); } catch (SecurityException x) { throw new ServiceConfigurationError(x); } } private static boolean loadProviderAsService() { Iterator i = Service.providers(SelectorProvider.class, ClassLoader.getSystemClassLoader()); for (;;) { try { if (!i.hasNext()) return false; provider = (SelectorProvider)i.next(); return true; } catch (ServiceConfigurationError sce) { if (sce.getCause() instanceof SecurityException) { // Ignore the security exception, try the next provider continue; } throw sce; } } } /** * Returns the system-wide default selector provider for this invocation of * the Java virtual machine. * * <p> The first invocation of this method locates the default provider * object as follows: </p> * * <ol> * * <li><p> If the system property * <tt>java.nio.channels.spi.SelectorProvider</tt> is defined then it is * taken to be the fully-qualified name of a concrete provider class. * The class is loaded and instantiated; if this process fails then an * unspecified error is thrown. </p></li> * * <li><p> If a provider class has been installed in a jar file that is * visible to the system class loader, and that jar file contains a * provider-configuration file named * <tt>java.nio.channels.spi.SelectorProvider</tt> in the resource * directory <tt>META-INF/services</tt>, then the first class name * specified in that file is taken. The class is loaded and * instantiated; if this process fails then an unspecified error is * thrown. </p></li> * * <li><p> Finally, if no provider has been specified by any of the above * means then the system-default provider class is instantiated and the * result is returned. </p></li> * * </ol> * * <p> Subsequent invocations of this method return the provider that was * returned by the first invocation. </p> * * @return The system-wide default selector provider */ public static SelectorProvider provider() { synchronized (lock) { if (provider != null) return provider; return (SelectorProvider)AccessController .doPrivileged(new PrivilegedAction() { public Object run() { if (loadProviderFromProperty()) return provider; if (loadProviderAsService()) return provider; provider = sun.nio.ch.DefaultSelectorProvider.create(); return provider; } }); } } /** * Opens a datagram channel. </p> * * @return The new channel */ public abstract DatagramChannel openDatagramChannel() throws IOException; /** * Opens a pipe. </p> * * @return The new pipe */ public abstract Pipe openPipe() throws IOException; /** * Opens a selector. </p> * * @return The new selector */ public abstract AbstractSelector openSelector() throws IOException; /** * Opens a server-socket channel. </p> * * @return The new channel */ public abstract ServerSocketChannel openServerSocketChannel() throws IOException; /** * Opens a socket channel. </p> * * @return The new channel */ public abstract SocketChannel openSocketChannel() throws IOException; /** * Returns the channel inherited from the entity that created this * Java virtual machine. * * <p> On many operating systems a process, such as a Java virtual * machine, can be started in a manner that allows the process to * inherit a channel from the entity that created the process. The * manner in which this is done is system dependent, as are the * possible entities to which the channel may be connected. For example, * on UNIX systems, the Internet services daemon (<i>inetd</i>) is used to * start programs to service requests when a request arrives on an * associated network port. In this example, the process that is started, * inherits a channel representing a network socket. * * <p> In cases where the inherited channel represents a network socket * then the {@link java.nio.channels.Channel Channel} type returned * by this method is determined as follows: * * <ul> * * <li><p> If the inherited channel represents a stream-oriented connected * socket then a {@link java.nio.channels.SocketChannel SocketChannel} is * returned. The socket channel is, at least initially, in blocking * mode, bound to a socket address, and connected to a peer. * </p></li> * * <li><p> If the inherited channel represents a stream-oriented listening * socket then a {@link java.nio.channels.ServerSocketChannel * ServerSocketChannel} is returned. The server-socket channel is, at * least initially, in blocking mode, and bound to a socket address. * </p></li> * * <li><p> If the inherited channel is a datagram-oriented socket * then a {@link java.nio.channels.DatagramChannel DatagramChannel} is * returned. The datagram channel is, at least initially, in blocking * mode, and bound to a socket address. * </p></li> * * </ul> * * <p> In addition to the network-oriented channels described, this method * may return other kinds of channels in the future. * * <p> The first invocation of this method creates the channel that is * returned. Subsequent invocations of this method return the same * channel. </p> * * @return The inherited channel, if any, otherwise <tt>null</tt>. * * @throws IOException * If an I/O error occurs * * @throws SecurityException * If a security manager has been installed and it denies * {@link RuntimePermission}<tt>("inheritedChannel")</tt> * * @since 1.5 */ public Channel inheritedChannel() throws IOException { return null; } }