changeset 170:a4733ce6bec9

8129106: Custom DeviceProvider implementation errors are not processed correctly by DeviceManager.open(...DeviceConfig...) methods Summary: DeviceProvider functions calls are wrapped with try-catch Reviewed-by: alkonsta
author snazarki
date Thu, 18 Jun 2015 13:20:08 +0300
parents 35bd126ae904
children dd0fc7e6d5f9
files src/share/classes/jdk/dio/DeviceManager.java
diffstat 1 files changed, 38 insertions(+), 50 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/jdk/dio/DeviceManager.java	Tue Jun 16 18:05:55 2015 +0300
+++ b/src/share/classes/jdk/dio/DeviceManager.java	Thu Jun 18 13:20:08 2015 +0300
@@ -37,15 +37,16 @@
 import com.oracle.dio.registry.RegistrationEventHandler;
 import com.oracle.dio.registry.RegistrationEventSender;
 import com.oracle.dio.registry.Registry;
+import com.oracle.dio.utils.Constants;
+import com.oracle.dio.utils.ExceptionMessage;
+import com.oracle.dio.utils.Logging;
+import com.oracle.dio.utils.PrivilegeController;
+import com.oracle.dio.utils.PrivilegedAction;
 
 import jdk.dio.spi.DeviceProvider;
+
 import romizer.Local;
 
-import com.oracle.dio.utils.Constants;
-import com.oracle.dio.utils.PrivilegeController;
-import com.oracle.dio.utils.PrivilegedAction;
-import com.oracle.dio.utils.ExceptionMessage;
-
 /**
  * The {@code DeviceManager} class provides methods for opening and registering
  * devices that can then be handled as {@link Device} instances. A device
@@ -304,13 +305,12 @@
             );
         }
         checkMode(mode);
-
+        PeripheralDescriptorImpl<DeviceConfig<P>, P> descr = new PeripheralDescriptorImpl(UNSPECIFIED_ID, null, config, intf, null);
         if (null != intf) {
-            PeripheralDescriptorImpl<DeviceConfig<P>, P> descr = new PeripheralDescriptorImpl(UNSPECIFIED_ID, null, config, intf, null);
             try {
                 return ((PeripheralFactory<P>)getFactory(intf)).create(descr, mode);
             } catch (DeviceNotFoundException | UnsupportedDeviceTypeException e) {
-                P res = (P)loadFromDriver(config, mode);
+                P res = (P)loadFromDriver(descr, mode);
                 if (null == res) {
                     throw e;
                 }
@@ -319,7 +319,7 @@
         } else {
             // special case: getDefaultType returns null that means config is not for embedded drivers
             // try to load from installed drivers
-            P res = (P)loadFromDriver(config, mode);
+            P res = (P)loadFromDriver(descr, mode);
             if (null == res) {
                 throw new UnsupportedDeviceTypeException(config.toString());
             }
@@ -500,8 +500,7 @@
         } catch (InvalidDeviceConfigException e) {
             throw new DeviceNotFoundException(e.getMessage());
         } catch (DeviceNotFoundException | UnsupportedDeviceTypeException e) {
-            DeviceConfig<? super P> config = descr.getConfiguration();
-            P res = (P)loadFromDriver(config, mode);
+            P res = (P)loadFromDriver(descr, mode);
             if (null == res) {
                 throw e;
             }
@@ -759,8 +758,7 @@
                 }
                 throw e2;
             } catch (DeviceNotFoundException | UnsupportedDeviceTypeException e) {
-                DeviceConfig<? super P> config = descr.getConfiguration();
-                P res = (P)loadFromDriver(config, mode);
+                P res = (P)loadFromDriver(descr, mode);
                 if (null == res) {
                     throw e;
                 }
@@ -1134,65 +1132,51 @@
     }
 
     // is called in response to UDTE and DNFE
-    private static <P extends Device<? super P>> P loadFromDriver(DeviceConfig<? super P> config, int mode) throws
+    private static <P extends Device<? super P>> P loadFromDriver(DeviceDescriptor<P> descr, int mode) throws
         DeviceNotFoundException, UnavailableDeviceException, InvalidDeviceConfigException,
         UnsupportedAccessModeException, IOException {
         ServiceLoader<DeviceProvider> loader = ServiceLoader.load(DeviceProvider.class);
         Iterator<DeviceProvider>  iter = loader.iterator();
-
+        final DeviceConfig<P> config = descr.getConfiguration();
+        final Class<P> type = descr.getInterface();
         boolean found = false;
         try {
             if (!iter.hasNext()) {
                 return null;
             }
 
-            int rejected, total;
-            rejected = total = 0;
-            while (iter.hasNext()) {
-                total++;
-                DeviceProvider provider = iter.next();
-                if (!provider.getConfigType().isAssignableFrom(config.getClass())) {
-                    rejected++;
-                }
-            }
-
-            if (rejected == total) {
-                // caller will rethrow UDTE or DNFE
-                return null;
-            }
-
-            iter = loader.iterator();
-
             while (iter.hasNext()) {
                 DeviceProvider provider = iter.next();
 
                 try {
-                    // properties was checked by Registry when descriptor was loaded up
-                    return (P)provider.open(config,null,mode);
-                } catch (UnavailableDeviceException e) {
-                    // throw UPE if sunsequent operation is not success
-                    found = true;
-                    continue;
-                } catch (DeviceNotFoundException e2) {
+                    if (provider.getConfigType().isAssignableFrom(config.getClass()) &&
+                        (null == type || provider.getType().isAssignableFrom(type))) {
+                        found = true;
+                        if (provider.matches(descr.getProperties())) {
+                            // properties was checked by Registry when descriptor was loaded up
+                            return (P)provider.open(config,descr.getProperties(),mode);
+                        }
+                    }
+                } catch (UnavailableDeviceException | InvalidDeviceConfigException | UnsupportedAccessModeException | SecurityException e) {
+                    // driver was found but it rejects provided data or device is busy or application has no rights to use the driver
+                    throw e;
+                } catch (Throwable  e3) {
+                    Logging.reportError("Provider " + provider + " throws " + e3);
                     // try other driver.
-                    // now there is no way to determine what driver accepts config with correct hardware information
-                    // therefore it is neccesarry to test all of them
                     continue;
                 }
-        }
+            }
         } catch (ServiceConfigurationError  ex) {
-                             // service framework exception equals to empty iterator
-                             return null;
+             // service framework exception equals to empty iterator
+             return null;
         }
         if (found) {
-            throw new UnavailableDeviceException(
-                ExceptionMessage.format(ExceptionMessage.DEVICE_FOUND_BUT_PERIPHERAL_IS_BUSY)
-            );
-        } else {
             throw new DeviceNotFoundException(
                 ExceptionMessage.format(ExceptionMessage.DEVICE_DRIVERS_NOT_MATCH)
             );
         }
+        // no driver matches descritor, caller will throw UDTE or DNFE
+        return null;
     }
 
 
@@ -1201,8 +1185,12 @@
         try {
             while (iter.hasNext()) {
                 DeviceProvider provider = iter.next();
-                if (provider.getType().isAssignableFrom(intf)) {
-                    return;
+                try {
+                    if (provider.getType().isAssignableFrom(intf)) {
+                        return;
+                    }
+                } catch (Throwable e) {
+                    // any exception threats as type is not suuported by provider
                 }
             }
         } catch (ServiceConfigurationError ex) {