jdk/src/share/classes/sun/rmi/server/Activation.java
changeset 9502 de183d393b77
parent 5506 202f599c92aa
child 12040 558b0e0d5910
equal deleted inserted replaced
9501:dbb0d972bf41 9502:de183d393b77
    28 import java.io.ByteArrayOutputStream;
    28 import java.io.ByteArrayOutputStream;
    29 import java.io.File;
    29 import java.io.File;
    30 import java.io.FileOutputStream;
    30 import java.io.FileOutputStream;
    31 import java.io.IOException;
    31 import java.io.IOException;
    32 import java.io.InputStream;
    32 import java.io.InputStream;
       
    33 import java.io.ObjectInputStream;
    33 import java.io.OutputStream;
    34 import java.io.OutputStream;
    34 import java.io.PrintStream;
    35 import java.io.PrintStream;
    35 import java.io.PrintWriter;
    36 import java.io.PrintWriter;
    36 import java.io.Serializable;
    37 import java.io.Serializable;
    37 import java.lang.Process;
    38 import java.lang.Process;
    96 import java.util.Map;
    97 import java.util.Map;
    97 import java.util.MissingResourceException;
    98 import java.util.MissingResourceException;
    98 import java.util.Properties;
    99 import java.util.Properties;
    99 import java.util.ResourceBundle;
   100 import java.util.ResourceBundle;
   100 import java.util.Set;
   101 import java.util.Set;
       
   102 import java.util.concurrent.ConcurrentHashMap;
   101 import sun.rmi.log.LogHandler;
   103 import sun.rmi.log.LogHandler;
   102 import sun.rmi.log.ReliableLog;
   104 import sun.rmi.log.ReliableLog;
   103 import sun.rmi.registry.RegistryImpl;
   105 import sun.rmi.registry.RegistryImpl;
   104 import sun.rmi.runtime.NewThreadAction;
   106 import sun.rmi.runtime.NewThreadAction;
   105 import sun.rmi.server.UnicastServerRef;
   107 import sun.rmi.server.UnicastServerRef;
   145     private static Method execPolicyMethod;
   147     private static Method execPolicyMethod;
   146     private static boolean debugExec;
   148     private static boolean debugExec;
   147 
   149 
   148     /** maps activation id to its respective group id */
   150     /** maps activation id to its respective group id */
   149     private Map<ActivationID,ActivationGroupID> idTable =
   151     private Map<ActivationID,ActivationGroupID> idTable =
   150         new HashMap<ActivationID,ActivationGroupID>();
   152         new ConcurrentHashMap<>();
   151     /** maps group id to its GroupEntry groups */
   153     /** maps group id to its GroupEntry groups */
   152     private Map<ActivationGroupID,GroupEntry> groupTable =
   154     private Map<ActivationGroupID,GroupEntry> groupTable =
   153         new HashMap<ActivationGroupID,GroupEntry>();
   155         new ConcurrentHashMap<>();
   154 
   156 
   155     private byte majorVersion = MAJOR_VERSION;
   157     private byte majorVersion = MAJOR_VERSION;
   156     private byte minorVersion = MINOR_VERSION;
   158     private byte minorVersion = MINOR_VERSION;
   157 
   159 
   158     /** number of simultaneous group exec's */
   160     /** number of simultaneous group exec's */
   234         numUpdates = 0;
   236         numUpdates = 0;
   235         shutdownHook =  new ShutdownHook();
   237         shutdownHook =  new ShutdownHook();
   236         groupSemaphore = getInt("sun.rmi.activation.groupThrottle", 3);
   238         groupSemaphore = getInt("sun.rmi.activation.groupThrottle", 3);
   237         groupCounter = 0;
   239         groupCounter = 0;
   238         Runtime.getRuntime().addShutdownHook(shutdownHook);
   240         Runtime.getRuntime().addShutdownHook(shutdownHook);
       
   241 
       
   242         // Use array size of 0, since the value from calling size()
       
   243         // may be out of date by the time toArray() is called.
   239         ActivationGroupID[] gids =
   244         ActivationGroupID[] gids =
   240             groupTable.keySet().toArray(
   245             groupTable.keySet().toArray(new ActivationGroupID[0]);
   241                 new ActivationGroupID[groupTable.size()]);
       
   242 
   246 
   243         synchronized (startupLock = new Object()) {
   247         synchronized (startupLock = new Object()) {
   244             // all the remote methods briefly synchronize on startupLock
   248             // all the remote methods briefly synchronize on startupLock
   245             // (via checkShutdown) to make sure they don't happen in the
   249             // (via checkShutdown) to make sure they don't happen in the
   246             // middle of this block.  This block must not cause any such
   250             // middle of this block.  This block must not cause any such
   272                 e.printStackTrace();
   276                 e.printStackTrace();
   273             }
   277             }
   274         }
   278         }
   275     }
   279     }
   276 
   280 
       
   281     /**
       
   282      * Previous versions used HashMap instead of ConcurrentHashMap.
       
   283      * Replace any HashMaps found during deserialization with
       
   284      * ConcurrentHashMaps.
       
   285      */
       
   286     private void readObject(ObjectInputStream ois)
       
   287         throws IOException, ClassNotFoundException
       
   288     {
       
   289         ois.defaultReadObject();
       
   290         if (! (groupTable instanceof ConcurrentHashMap)) {
       
   291             groupTable = new ConcurrentHashMap<>(groupTable);
       
   292         }
       
   293         if (! (idTable instanceof ConcurrentHashMap)) {
       
   294             idTable = new ConcurrentHashMap<>(idTable);
       
   295         }
       
   296     }
       
   297 
   277     private static class SystemRegistryImpl extends RegistryImpl {
   298     private static class SystemRegistryImpl extends RegistryImpl {
   278 
   299 
   279         private static final String NAME = ActivationSystem.class.getName();
   300         private static final String NAME = ActivationSystem.class.getName();
   280         private final ActivationSystem systemStub;
   301         private final ActivationSystem systemStub;
   281 
   302 
   486             checkArgs(desc, null);
   507             checkArgs(desc, null);
   487 
   508 
   488             ActivationGroupID id = new ActivationGroupID(systemStub);
   509             ActivationGroupID id = new ActivationGroupID(systemStub);
   489             GroupEntry entry = new GroupEntry(id, desc);
   510             GroupEntry entry = new GroupEntry(id, desc);
   490             // table insertion must take place before log update
   511             // table insertion must take place before log update
   491             synchronized (groupTable) {
   512             groupTable.put(id, entry);
   492                 groupTable.put(id, entry);
       
   493             }
       
   494             addLogRecord(new LogRegisterGroup(id, desc));
   513             addLogRecord(new LogRegisterGroup(id, desc));
   495             return id;
   514             return id;
   496         }
   515         }
   497 
   516 
   498         public ActivationMonitor activeGroup(ActivationGroupID id,
   517         public ActivationMonitor activeGroup(ActivationGroupID id,
   513             checkShutdown();
   532             checkShutdown();
   514             RegistryImpl.checkAccess("ActivationSystem.unregisterGroup");
   533             RegistryImpl.checkAccess("ActivationSystem.unregisterGroup");
   515 
   534 
   516             // remove entry before unregister so state is updated before
   535             // remove entry before unregister so state is updated before
   517             // logged
   536             // logged
   518             synchronized (groupTable) {
   537             removeGroupEntry(id).unregisterGroup(true);
   519                 GroupEntry entry = getGroupEntry(id);
       
   520                 groupTable.remove(id);
       
   521                 entry.unregisterGroup(true);
       
   522             }
       
   523         }
   538         }
   524 
   539 
   525         public ActivationDesc setActivationDesc(ActivationID id,
   540         public ActivationDesc setActivationDesc(ActivationID id,
   526                                                 ActivationDesc desc)
   541                                                 ActivationDesc desc)
   527             throws ActivationException, UnknownObjectException, RemoteException
   542             throws ActivationException, UnknownObjectException, RemoteException
   635                  */
   650                  */
   636                 unexport(activator);
   651                 unexport(activator);
   637                 unexport(system);
   652                 unexport(system);
   638 
   653 
   639                 // destroy all child processes (groups)
   654                 // destroy all child processes (groups)
   640                 GroupEntry[] groupEntries;
   655                 for (GroupEntry groupEntry : groupTable.values()) {
   641                 synchronized (groupTable) {
       
   642                     groupEntries = groupTable.values().
       
   643                         toArray(new GroupEntry[groupTable.size()]);
       
   644                 }
       
   645                 for (GroupEntry groupEntry : groupEntries) {
       
   646                     groupEntry.shutdown();
   656                     groupEntry.shutdown();
   647                 }
   657                 }
   648 
   658 
   649                 Runtime.getRuntime().removeShutdownHook(shutdownHook);
   659                 Runtime.getRuntime().removeShutdownHook(shutdownHook);
   650 
   660 
   691             synchronized (Activation.this) {
   701             synchronized (Activation.this) {
   692                 shuttingDown = true;
   702                 shuttingDown = true;
   693             }
   703             }
   694 
   704 
   695             // destroy all child processes (groups) quickly
   705             // destroy all child processes (groups) quickly
   696             synchronized (groupTable) {
   706             for (GroupEntry groupEntry : groupTable.values()) {
   697                 for (GroupEntry groupEntry : groupTable.values()) {
   707                 groupEntry.shutdownFast();
   698                     groupEntry.shutdownFast();
       
   699                 }
       
   700             }
   708             }
   701         }
   709         }
   702     }
   710     }
   703 
   711 
   704     /**
   712     /**
   706      * Throws UnknownObjectException if the object is not registered.
   714      * Throws UnknownObjectException if the object is not registered.
   707      */
   715      */
   708     private ActivationGroupID getGroupID(ActivationID id)
   716     private ActivationGroupID getGroupID(ActivationID id)
   709         throws UnknownObjectException
   717         throws UnknownObjectException
   710     {
   718     {
   711         synchronized (idTable) {
   719         ActivationGroupID groupID = idTable.get(id);
   712             ActivationGroupID groupID = idTable.get(id);
   720         if (groupID != null) {
   713             if (groupID != null) {
   721             return groupID;
   714                 return groupID;
       
   715             }
       
   716         }
   722         }
   717         throw new UnknownObjectException("unknown object: " + id);
   723         throw new UnknownObjectException("unknown object: " + id);
       
   724     }
       
   725 
       
   726     /**
       
   727      * Returns the group entry for the group id, optionally removing it.
       
   728      * Throws UnknownGroupException if the group is not registered.
       
   729      */
       
   730     private GroupEntry getGroupEntry(ActivationGroupID id, boolean rm)
       
   731         throws UnknownGroupException
       
   732     {
       
   733         if (id.getClass() == ActivationGroupID.class) {
       
   734             GroupEntry entry;
       
   735             if (rm) {
       
   736                 entry = groupTable.remove(id);
       
   737             } else {
       
   738                 entry = groupTable.get(id);
       
   739             }
       
   740             if (entry != null && !entry.removed) {
       
   741                 return entry;
       
   742             }
       
   743         }
       
   744         throw new UnknownGroupException("group unknown");
   718     }
   745     }
   719 
   746 
   720     /**
   747     /**
   721      * Returns the group entry for the group id. Throws
   748      * Returns the group entry for the group id. Throws
   722      * UnknownGroupException if the group is not registered.
   749      * UnknownGroupException if the group is not registered.
   723      */
   750      */
   724     private GroupEntry getGroupEntry(ActivationGroupID id)
   751     private GroupEntry getGroupEntry(ActivationGroupID id)
   725         throws UnknownGroupException
   752         throws UnknownGroupException
   726     {
   753     {
   727         if (id.getClass() == ActivationGroupID.class) {
   754         return getGroupEntry(id, false);
   728             synchronized (groupTable) {
   755     }
   729                 GroupEntry entry = groupTable.get(id);
   756 
   730                 if (entry != null && !entry.removed) {
   757     /**
   731                     return entry;
   758      * Removes and returns the group entry for the group id. Throws
   732                 }
   759      * UnknownGroupException if the group is not registered.
   733             }
   760      */
   734         }
   761     private GroupEntry removeGroupEntry(ActivationGroupID id)
   735         throw new UnknownGroupException("group unknown");
   762         throws UnknownGroupException
       
   763     {
       
   764         return getGroupEntry(id, true);
   736     }
   765     }
   737 
   766 
   738     /**
   767     /**
   739      * Returns the group entry for the object's id. Throws
   768      * Returns the group entry for the object's id. Throws
   740      * UnknownObjectException if the object is not registered or the
   769      * UnknownObjectException if the object is not registered or the
   742      */
   771      */
   743     private GroupEntry getGroupEntry(ActivationID id)
   772     private GroupEntry getGroupEntry(ActivationID id)
   744         throws UnknownObjectException
   773         throws UnknownObjectException
   745     {
   774     {
   746         ActivationGroupID gid = getGroupID(id);
   775         ActivationGroupID gid = getGroupID(id);
   747         synchronized (groupTable) {
   776         GroupEntry entry = groupTable.get(gid);
   748             GroupEntry entry = groupTable.get(gid);
   777         if (entry != null && !entry.removed) {
   749             if (entry != null) {
   778             return entry;
   750                 return entry;
       
   751             }
       
   752         }
   779         }
   753         throw new UnknownObjectException("object's group removed");
   780         throw new UnknownObjectException("object's group removed");
   754     }
   781     }
   755 
   782 
   756     /**
   783     /**
   880             if (desc.getRestartMode() == true) {
   907             if (desc.getRestartMode() == true) {
   881                 restartSet.add(id);
   908                 restartSet.add(id);
   882             }
   909             }
   883 
   910 
   884             // table insertion must take place before log update
   911             // table insertion must take place before log update
   885             synchronized (idTable) {
   912             idTable.put(id, groupID);
   886                 idTable.put(id, groupID);
       
   887             }
       
   888 
   913 
   889             if (addRecord) {
   914             if (addRecord) {
   890                 addLogRecord(new LogRegisterObject(id, desc));
   915                 addLogRecord(new LogRegisterObject(id, desc));
   891             }
   916             }
   892         }
   917         }
   899             objects.remove(id);
   924             objects.remove(id);
   900             if (objEntry.desc.getRestartMode() == true) {
   925             if (objEntry.desc.getRestartMode() == true) {
   901                 restartSet.remove(id);
   926                 restartSet.remove(id);
   902             }
   927             }
   903 
   928 
   904             // table insertion must take place before log update
   929             // table removal must take place before log update
   905             synchronized (idTable) {
   930             idTable.remove(id);
   906                 idTable.remove(id);
       
   907             }
       
   908             if (addRecord) {
   931             if (addRecord) {
   909                 addLogRecord(new LogUnregisterObject(id));
   932                 addLogRecord(new LogUnregisterObject(id));
   910             }
   933             }
   911         }
   934         }
   912 
   935 
   917             removed = true;
   940             removed = true;
   918             for (Map.Entry<ActivationID,ObjectEntry> entry :
   941             for (Map.Entry<ActivationID,ObjectEntry> entry :
   919                      objects.entrySet())
   942                      objects.entrySet())
   920             {
   943             {
   921                 ActivationID id = entry.getKey();
   944                 ActivationID id = entry.getKey();
   922                 synchronized (idTable) {
   945                 idTable.remove(id);
   923                     idTable.remove(id);
       
   924                 }
       
   925                 ObjectEntry objEntry = entry.getValue();
   946                 ObjectEntry objEntry = entry.getValue();
   926                 objEntry.removed = true;
   947                 objEntry.removed = true;
   927             }
   948             }
   928             objects.clear();
   949             objects.clear();
   929             restartSet.clear();
   950             restartSet.clear();