/** * Remove endpoint from the reference set. */ synchronized private void refSetRemove(VMID vmid) { // remove notification request DGCImpl.getDGCImpl().unregisterTarget(vmid, this); if (refSet.removeElement(vmid) && refSet.isEmpty()) { // reference set is empty, so server can be garbage collected. // remove object from table. if (DGCImpl.dgcLog.isLoggable(Log.VERBOSE)) { DGCImpl.dgcLog.log(Log.VERBOSE, "reference set is empty: target = " + this); } /* * If the remote object implements the Unreferenced interface, * invoke its unreferenced callback in a separate thread. */ Remote obj = getImpl(); if (obj instanceof Unreferenced) { final Unreferenced unrefObj = (Unreferenced) obj; AccessController.doPrivileged( new NewThreadAction(() -> { Thread.currentThread().setContextClassLoader(ccl); AccessController.doPrivileged((PrivilegedAction<Void>) () -> { unrefObj.unreferenced(); return null; }, acc); }, "Unreferenced-" + nextThreadNum++, false, true)).start(); // REMIND: access to nextThreadNum not synchronized; you care? } unpinImpl(); } }
private synchronized void unreferenced() { final Object obj = ref.get(); if (obj instanceof Unreferenced) { /* * Spawn unreferenced thread. * Start this thread with setDaemon(false) to protect VM * from exiting while unreferencing the object. * The thread is started in non-system group * (see comment for CreateThreadAction class). */ Thread uThread = ((Thread) AccessController.doPrivileged( new CreateThreadAction(new Runnable() { public void run() { AccessController.doPrivileged( new PrivilegedAction() { public Object run() { ((Unreferenced) obj).unreferenced(); return null; } }, acc); } }, "Unreferenced", false, false))); //$NON-NLS-1$ uThread.setContextClassLoader(loader); uThread.start(); } ref.makeStrong(false); }
/** * A per {@link java.rmi.dgc.DGC#clean(ObjID[], long, VMID, boolean)} * implementation of the dirty method * * @param vmid * The {@link java.rmi.dgc.VMID} updated. * @see java.rmi.dgc.DGC */ public final void clean(VMID vmid) { if (vmIdExpirationTimeMap.containsKey(vmid)) { vmIdExpirationTimeMap.remove(vmid); dgcCount--; if (vmIdExpirationTimeMap.isEmpty()) { if (StrongRef instanceof Unreferenced) { ((Unreferenced) StrongRef).unreferenced(); } StrongRef = null; } } }
/** * Eliminates the VMID's which's lease times had expired. * * @param time * The time to be taken as bound. * @return the eliminated VMIDs. */ public final Set<VMID> removeOlderThan(long time) { /* * The return value is not necesary, is there just for possible * extensions. */ HashSet<VMID> retVMIDs = new HashSet<VMID>(); synchronized (vmIdExpirationTimeMap) { Iterator<VMID> iter = vmIdExpirationTimeMap.keySet().iterator(); while (iter.hasNext()) { VMID currentVMID = iter.next(); Long iterTime = vmIdExpirationTimeMap.get(currentVMID); if (iterTime < time) { iter.remove(); dgcCount--; if (vmIdExpirationTimeMap.isEmpty()) { if (StrongRef instanceof Unreferenced) { ((Unreferenced) StrongRef).unreferenced(); } StrongRef = null; } retVMIDs.add(currentVMID); } } } return retVMIDs; }
/** * Remove endpoint from the reference set. */ synchronized private void refSetRemove(VMID vmid) { // remove notification request DGCImpl.getDGCImpl().unregisterTarget(vmid, this); if (refSet.removeElement(vmid) && refSet.isEmpty()) { // reference set is empty, so server can be garbage collected. // remove object from table. if (DGCImpl.dgcLog.isLoggable(Log.VERBOSE)) { DGCImpl.dgcLog.log(Log.VERBOSE, "reference set is empty: target = " + this); } /* * If the remote object implements the Unreferenced interface, * invoke its unreferenced callback in a separate thread. */ Remote obj = getImpl(); if (obj instanceof Unreferenced) { final Unreferenced unrefObj = (Unreferenced) obj; final Thread t = java.security.AccessController.doPrivileged( new NewThreadAction(new Runnable() { public void run() { unrefObj.unreferenced(); } }, "Unreferenced-" + nextThreadNum++, false, true)); // REMIND: access to nextThreadNum not synchronized; you care? /* * We must manually set the context class loader appropriately * for threads that may invoke user code (see bugid 4171278). */ java.security.AccessController.doPrivileged( new java.security.PrivilegedAction<Void>() { public Void run() { t.setContextClassLoader(ccl); return null; } }); t.start(); } unpinImpl(); } }