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