VirtualBox

Changeset 61203 in vbox for trunk/src/VBox/Main/glue


Ignore:
Timestamp:
May 26, 2016 8:31:43 AM (9 years ago)
Author:
vboxsync
Message:

bugref:8347: Main/glue/glue-java.xsl: Fix java webservice bindings from leaking all server side objects because they are not released when the stubs on the client are garbage collected

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/glue/glue-java.xsl

    r61165 r61203  
    648648
    649649<xsl:template name="startExcWrapper">
     650  <xsl:param name="preventObjRelease" />
     651
     652  <xsl:if test="$G_vboxGlueStyle='jaxws' and $preventObjRelease">
     653    <xsl:text>        this.getObjMgr().preventObjRelease();&#10;</xsl:text>
     654  </xsl:if>
    650655  <xsl:text>        try&#10;</xsl:text>
    651656  <xsl:text>        {&#10;</xsl:text>
     
    653658
    654659<xsl:template name="endExcWrapper">
     660  <xsl:param name="allowObjRelease" />
    655661
    656662  <xsl:choose>
     
    675681      <xsl:text>        catch (InvalidObjectFaultMsg e)&#10;</xsl:text>
    676682      <xsl:text>        {&#10;</xsl:text>
    677       <xsl:text>            throw new VBoxException(e.getMessage(), e, this.port);&#10;</xsl:text>
     683      <xsl:text>            throw new VBoxException(e.getMessage(), e, this.getObjMgr(), this.port);&#10;</xsl:text>
    678684      <xsl:text>        }&#10;</xsl:text>
    679685      <xsl:text>        catch (RuntimeFaultMsg e)&#10;</xsl:text>
    680686      <xsl:text>        {&#10;</xsl:text>
    681       <xsl:text>            throw new VBoxException(e.getMessage(), e, this.port);&#10;</xsl:text>
     687      <xsl:text>            throw new VBoxException(e.getMessage(), e, this.getObjMgr(), this.port);&#10;</xsl:text>
    682688      <xsl:text>        }&#10;</xsl:text>
     689      <xsl:if test="$allowObjRelease">
     690        <xsl:text>        finally&#10;</xsl:text>
     691        <xsl:text>        {&#10;</xsl:text>
     692        <xsl:text>            getObjMgr().allowObjRelease();&#10;</xsl:text>
     693        <xsl:text>        }&#10;</xsl:text>
     694      </xsl:if>
    683695    </xsl:when>
    684696
     
    11601172      <xsl:choose>
    11611173        <xsl:when test="$isstruct">
    1162           <xsl:value-of select="concat('Helper.wrap2(', $elemgluetype, '.class, ', $elembacktype, '.class, port, ', $value, ')')"/>
     1174          <xsl:value-of select="concat('Helper.wrap2(', $elemgluetype, '.class, ', $elembacktype, '.class, objMgr, port, ', $value, ')')"/>
    11631175        </xsl:when>
    11641176        <xsl:when test="count(key('G_keyEnumsByName', $idltype)) > 0">
     
    11661178        </xsl:when>
    11671179        <xsl:when test="$idltype = '$unknown' or (count(key('G_keyInterfacesByName', $idltype)) > 0)">
    1168           <xsl:value-of select="concat('Helper.wrap(', $elemgluetype, '.class, port, ', $value, ')')"/>
     1180          <xsl:value-of select="concat('Helper.wrap(', $elemgluetype, '.class, getObjMgr(), port, ', $value, ')')"/>
    11691181        </xsl:when>
    11701182        <xsl:when test="$idltype='octet'">
     
    12101222        </xsl:when>
    12111223        <xsl:when test="$isstruct">
    1212           <xsl:value-of select="concat('(', $value, ' != null) ? new ', $gluetype, '(', $value, ', port) : null')" />
     1224          <xsl:value-of select="concat('(', $value, ' != null) ? new ', $gluetype, '(', $value, ', getObjMgr(), port) : null')" />
    12131225        </xsl:when>
    12141226        <xsl:when test="$idltype = '$unknown' or (count(key('G_keyInterfacesByName', $idltype)) > 0)">
    12151227          <!-- if the MOR string is empty, that means NULL, so return NULL instead of an object then -->
    1216           <xsl:value-of select="concat('(', $value, '.length() > 0) ? new ', $gluetype, '(', $value, ', port) : null')" />
     1228          <xsl:value-of select="concat('(', $value, '.length() > 0) ? new ', $gluetype, '(', $value, ', getObjMgr(), port) : null')" />
    12171229        </xsl:when>
    12181230        <xsl:otherwise>
     
    18511863
    18521864  <xsl:value-of select="concat('    private ', $G_virtualBoxPackageCom, '.', $ifname, ' real;&#10;')"/>
    1853   <xsl:text>    private VboxPortType port;&#10;&#10;</xsl:text>
    1854 
    1855   <xsl:value-of select="concat('    public ', $ifname, '(', $G_virtualBoxPackageCom, '.', $ifname, ' real, VboxPortType port)&#10;')" />
     1865  <xsl:text>    private VboxPortType port;&#10;</xsl:text>
     1866  <xsl:text>    private ObjectRefManager objMgr;&#10;</xsl:text>
     1867
     1868  <!-- For structs which contain references to other objects we have to create the stub object during construction time
     1869       or it is possible that the reference was released by the garbage collector because the reference is not
     1870       accounted for. -->
     1871  <!-- Create the private members for containing objects here. -->
     1872  <xsl:for-each select="attribute">
     1873    <xsl:variable name="attrname"><xsl:value-of select="@name" /></xsl:variable>
     1874    <xsl:variable name="attrtype"><xsl:value-of select="@type" /></xsl:variable>
     1875    <xsl:variable name="attrsafearray"><xsl:value-of select="@safearray" /></xsl:variable>
     1876
     1877    <xsl:if test="(not(@wsmap = 'suppress')) and ($attrtype = '$unknown' or (count(key('G_keyInterfacesByName', $attrtype)) > 0))">
     1878      <xsl:variable name="gluegettertype">
     1879        <xsl:call-template name="typeIdl2Glue">
     1880          <xsl:with-param name="type" select="$attrtype" />
     1881          <xsl:with-param name="safearray" select="@safearray" />
     1882        </xsl:call-template>
     1883      </xsl:variable>
     1884      <xsl:value-of select="concat('    private ', $gluegettertype, ' ', $attrname, ';&#10;')" />
     1885    </xsl:if>
     1886  </xsl:for-each>
     1887
     1888  <xsl:value-of select="concat('&#10;    public ', $ifname, '(', $G_virtualBoxPackageCom, '.', $ifname, ' real, ObjectRefManager objMgr, VboxPortType port)&#10;')" />
    18561889  <xsl:text>    {&#10;</xsl:text>
    18571890  <xsl:text>        this.real = real;&#10;</xsl:text>
    18581891  <xsl:text>        this.port = port;&#10;</xsl:text>
     1892  <xsl:text>        this.objMgr = objMgr;&#10;</xsl:text>
     1893  <!-- Construct stub objects for every attribute containing a reference to a webserver side object -->
     1894  <xsl:for-each select="attribute">
     1895    <xsl:variable name="attrname"><xsl:value-of select="@name" /></xsl:variable>
     1896    <xsl:variable name="attrtype"><xsl:value-of select="@type" /></xsl:variable>
     1897    <xsl:variable name="attrsafearray"><xsl:value-of select="@safearray" /></xsl:variable>
     1898
     1899    <xsl:if test="(not(@wsmap = 'suppress')) and ($attrtype = '$unknown' or (count(key('G_keyInterfacesByName', $attrtype)) > 0))">
     1900      <xsl:variable name="backgettername">
     1901        <xsl:choose>
     1902          <!-- Stupid, but backend boolean getters called isFoo(), not getFoo() -->
     1903          <xsl:when test="$attrtype = 'boolean'">
     1904            <xsl:variable name="capsname">
     1905              <xsl:call-template name="capitalize">
     1906                <xsl:with-param name="str" select="$attrname" />
     1907              </xsl:call-template>
     1908            </xsl:variable>
     1909            <xsl:value-of select="concat('is', $capsname)" />
     1910          </xsl:when>
     1911          <xsl:otherwise>
     1912            <xsl:call-template name="makeGetterName">
     1913              <xsl:with-param name="attrname" select="$attrname" />
     1914            </xsl:call-template>
     1915          </xsl:otherwise>
     1916        </xsl:choose>
     1917      </xsl:variable>
     1918
     1919      <xsl:variable name="wrapped">
     1920      <xsl:call-template name="cookOutParam">
     1921        <xsl:with-param name="value" select="concat('real.', $backgettername, '()')" />
     1922        <xsl:with-param name="idltype" select="$attrtype" />
     1923        <xsl:with-param name="safearray" select="@safearray" />
     1924      </xsl:call-template>
     1925      </xsl:variable>
     1926      <xsl:value-of select="concat('        ', $attrname, ' = ', $wrapped, ';&#10;')" />
     1927    </xsl:if>
     1928  </xsl:for-each>
    18591929  <xsl:text>    }&#10;&#10;</xsl:text>
     1930
     1931  <xsl:text><![CDATA[    private ObjectRefManager getObjMgr()
     1932    {
     1933        return this.objMgr;
     1934    }
     1935]]></xsl:text>
    18601936
    18611937  <xsl:for-each select="attribute">
     
    19121988      </xsl:variable>
    19131989
     1990      <!-- For attributes containing a reference to another object just return the already cerated stub -->
    19141991      <xsl:apply-templates select="desc" mode="attribute_get"/>
    19151992      <xsl:value-of select="concat('    public ', $gluegettertype, ' ', $gluegettername, '()&#10;')" />
    19161993      <xsl:text>    {&#10;</xsl:text>
    1917       <xsl:value-of select="concat('        ', $backgettertype, ' retVal = real.', $backgettername, '();&#10;')" />
    1918       <xsl:variable name="wrapped">
    1919         <xsl:call-template name="cookOutParam">
    1920           <xsl:with-param name="value" select="'retVal'" />
    1921           <xsl:with-param name="idltype" select="$attrtype" />
    1922           <xsl:with-param name="safearray" select="@safearray" />
    1923         </xsl:call-template>
    1924       </xsl:variable>
    1925       <xsl:value-of select="concat('        return ', $wrapped, ';&#10;')" />
     1994      <xsl:choose>
     1995        <xsl:when test="$attrtype = '$unknown' or (count(key('G_keyInterfacesByName', $attrtype)) > 0)">
     1996          <xsl:value-of select="concat('        return ', $attrname, ';&#10;')" />
     1997        </xsl:when>
     1998        <xsl:otherwise>
     1999          <xsl:value-of select="concat('        ', $backgettertype, ' retVal = real.', $backgettername, '();&#10;')" />
     2000          <xsl:variable name="wrapped">
     2001            <xsl:call-template name="cookOutParam">
     2002              <xsl:with-param name="value" select="'retVal'" />
     2003              <xsl:with-param name="idltype" select="$attrtype" />
     2004              <xsl:with-param name="safearray" select="@safearray" />
     2005            </xsl:call-template>
     2006          </xsl:variable>
     2007          <xsl:value-of select="concat('        return ', $wrapped, ';&#10;')" />
     2008        </xsl:otherwise>
     2009      </xsl:choose>
    19262010      <xsl:text>    }&#10;</xsl:text>
    19272011    </xsl:if>
     
    20012085      <xsl:text>    {&#10;</xsl:text>
    20022086
    2003       <xsl:call-template name="startExcWrapper"/>
     2087      <xsl:call-template name="startExcWrapper">
     2088          <xsl:with-param name="preventObjRelease" select="$hasReturnParms and ($returnidltype = '$unknown' or (count(key('G_keyInterfacesByName', $returnidltype)) > 0))" />
     2089      </xsl:call-template>
    20042090
    20052091      <!-- declare temp out params -->
     
    20952181          </xsl:call-template>
    20962182        </xsl:variable>
    2097         <xsl:value-of select="concat('            return ', $wrapped, ';&#10;')" />
     2183        <xsl:value-of select="concat('           return ', $wrapped, ';&#10;')" />
    20982184      </xsl:if>
    2099       <xsl:call-template name="endExcWrapper"/>
     2185      <xsl:call-template name="endExcWrapper">
     2186        <xsl:with-param name="allowObjRelease" select="$hasReturnParms and ($returnidltype = '$unknown' or (count(key('G_keyInterfacesByName', $returnidltype)) > 0))" />
     2187      </xsl:call-template>
    21002188
    21012189      <xsl:text>    }&#10;</xsl:text>
     
    21822270    <xsl:when test="$G_vboxGlueStyle='jaxws'">
    21832271      <!-- bad, need to check that we really can be casted to this type -->
    2184       <xsl:value-of select="concat('        return obj == null ?  null : new ', $ifname, '(obj.getWrapped(), obj.getRemoteWSPort());&#10;')" />
     2272      <xsl:value-of select="concat('        return obj == null ?  null : new ', $ifname, '(obj.getWrapped(), obj.getObjMgr(), obj.getRemoteWSPort());&#10;')" />
    21852273    </xsl:when>
    21862274
     
    23782466  <xsl:choose>
    23792467      <xsl:when test="($G_vboxGlueStyle='jaxws')">
    2380         <xsl:value-of select="concat('    public ', $ifname, '(String wrapped, VboxPortType port)&#10;')" />
     2468        <xsl:value-of select="concat('    public ', $ifname, '(String wrapped, ObjectRefManager objMgr, VboxPortType port)&#10;')" />
    23812469        <xsl:text>    {&#10;</xsl:text>
    2382         <xsl:text>        super(wrapped, port);&#10;</xsl:text>
     2470        <xsl:text>        super(wrapped, objMgr, port);&#10;</xsl:text>
    23832471        <xsl:text>    }&#10;</xsl:text>
    23842472      </xsl:when>
     
    24472535        <xsl:text>    {&#10;</xsl:text>
    24482536
    2449         <xsl:call-template name="startExcWrapper"/>
     2537
     2538        <xsl:call-template name="startExcWrapper">
     2539          <xsl:with-param name="preventObjRelease" select="$attrtype = '$unknown' or (count(key('G_keyInterfacesByName', $attrtype)) > 0)" />
     2540        </xsl:call-template>
    24502541
    24512542        <!-- Actual getter implementation -->
     
    24582549
    24592550        <xsl:value-of select="concat('            return ', $wrapped, ';&#10;')" />
    2460         <xsl:call-template name="endExcWrapper"/>
     2551
     2552        <xsl:call-template name="endExcWrapper">
     2553          <xsl:with-param name="allowObjRelease" select="$attrtype = '$unknown' or (count(key('G_keyInterfacesByName', $attrtype)) > 0)" />
     2554        </xsl:call-template>
    24612555
    24622556        <xsl:text>    }&#10;</xsl:text>
     
    39214015{
    39224016    protected String obj;
     4017    protected ObjectRefManager objMgr;
    39234018    protected final VboxPortType port;
    39244019
    3925     public IUnknown(String obj, VboxPortType port)
    3926     {
    3927         this.obj = obj;
    3928         this.port = port;
     4020    public IUnknown(String obj, ObjectRefManager objMgr, VboxPortType port)
     4021    {
     4022        this.obj    = obj;
     4023        this.objMgr = objMgr;
     4024        this.port   = port;
     4025        objMgr.registerObj(this);
    39294026    }
    39304027
     
    39374034    {
    39384035        return this.port;
     4036    }
     4037
     4038    public final ObjectRefManager getObjMgr()
     4039    {
     4040        return this.objMgr;
    39394041    }
    39404042
     
    39844086public class Helper
    39854087{
    3986     public static <T> List<T> wrap(Class<T> wrapperClass, VboxPortType pt, List<String> values)
     4088    public static <T> List<T> wrap(Class<T> wrapperClass, ObjectRefManager objMgr, VboxPortType pt, List<String> values)
    39874089    {
    39884090        try
     
    39914093                return null;
    39924094
    3993             Constructor<T> c = wrapperClass.getConstructor(String.class, VboxPortType.class);
     4095            Constructor<T> c = wrapperClass.getConstructor(String.class, ObjectRefManager.class, VboxPortType.class);
    39944096            List<T> ret = new ArrayList<T>(values.size());
    39954097            for (String v : values)
    39964098            {
    3997                 ret.add(c.newInstance(v, pt));
     4099                ret.add(c.newInstance(v, objMgr, pt));
    39984100            }
    39994101            return ret;
     
    40174119    }
    40184120
    4019     public static <T1, T2> List<T1> wrap2(Class<T1> wrapperClass1, Class<T2> wrapperClass2, VboxPortType pt, List<T2> values)
     4121    public static <T1, T2> List<T1> wrap2(Class<T1> wrapperClass1, Class<T2> wrapperClass2, ObjectRefManager objMgr, VboxPortType pt, List<T2> values)
    40204122    {
    40214123        try
     
    40244126                return null;
    40254127
    4026             Constructor<T1> c = wrapperClass1.getConstructor(wrapperClass2, VboxPortType.class);
     4128            Constructor<T1> c = wrapperClass1.getConstructor(wrapperClass2, ObjectRefManager.class, VboxPortType.class);
    40274129            List<T1> ret = new ArrayList<T1>(values.size());
    40284130            for (T2 v : values)
    40294131            {
    4030                 ret.add(c.newInstance(v, pt));
     4132                ret.add(c.newInstance(v, objMgr, pt));
    40314133            }
    40324134            return ret;
     
    42534355    }
    42544356
    4255     public VBoxException(String message, Throwable cause, VboxPortType port)
     4357    public VBoxException(String message, Throwable cause, ObjectRefManager objMgr, VboxPortType port)
    42564358    {
    42574359        super(message, cause);
     
    42624364            resultCode = f.getResultCode();
    42634365            String retVal = f.getReturnval();
    4264             errorInfo = (retVal.length() > 0) ? new IVirtualBoxErrorInfo(retVal, port) : null;
     4366            errorInfo = (retVal.length() > 0) ? new IVirtualBoxErrorInfo(retVal, objMgr, port) : null;
    42654367        }
    42664368        else
     
    42934395    <xsl:text>import java.net.URL;
    42944396import java.math.BigInteger;
     4397import java.util.Iterator;
    42954398import java.util.List;
     4399import java.util.LinkedList;
    42964400import java.util.Map;
    42974401import java.util.HashMap;
    42984402import java.util.ArrayList;
     4403import java.util.concurrent.ConcurrentHashMap;
     4404import java.util.concurrent.ConcurrentLinkedQueue;
     4405import java.util.concurrent.ConcurrentMap;
     4406import java.util.concurrent.locks.ReentrantReadWriteLock;
     4407import java.lang.Integer;
     4408import java.lang.ref.WeakReference;
     4409import java.lang.ref.ReferenceQueue;
    42994410import javax.xml.namespace.QName;
    43004411import javax.xml.ws.BindingProvider;
     
    44244535
    44254536
     4537/**
     4538 * This class manages the object references between us and the webservice server.
     4539 * It makes sure that the object on the server side is destroyed when all
     4540 */
     4541class ObjectRefManager
     4542{
     4543    private final static ReferenceQueue<IUnknown> refQ = new ReferenceQueue<IUnknown>();
     4544
     4545    private final VboxPortType port;
     4546    private final ConcurrentMap<String, ManagedObj> map = new ConcurrentHashMap<String, ManagedObj>();
     4547    private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
     4548    private final ObjRefMgrCleanupThread objRefMgrCleanup;
     4549
     4550    public ObjectRefManager(VboxPortType port)
     4551    {
     4552        this.port = port;
     4553        this.objRefMgrCleanup = new ObjRefMgrCleanupThread(this, 100);
     4554        this.objRefMgrCleanup.start();
     4555    }
     4556
     4557    /**
     4558     * Prevents the object reference manager cleanup thread from releasing any
     4559     * server side objects to avoid a fundamental race in the multi threaded
     4560     * java environment where it is possible that a wrapper got the object ID
     4561     * from the server but couldn't create the local stub protecting the object
     4562     * before the cleanup thread released it.
     4563     */
     4564    public void preventObjRelease()
     4565    {
     4566        lock.readLock().lock();
     4567    }
     4568
     4569    /**
     4570     * Allows releasing server side objects from the cleanup thread again.
     4571     */
     4572    public void allowObjRelease()
     4573    {
     4574        lock.readLock().unlock();
     4575    }
     4576
     4577    /**
     4578     * Marks the start of a run to release server side objects which don't hold
     4579     * a reference locally anymore.
     4580     */
     4581    public void startObjRelease()
     4582    {
     4583        lock.writeLock().lock();
     4584    }
     4585
     4586    /**
     4587     * Marks the end of a cleanup run.
     4588     */
     4589    public void endObjRelease()
     4590    {
     4591        lock.writeLock().unlock();
     4592    }
     4593
     4594    /**
     4595     * Registers a new stub object for automatic reference managing.
     4596     */
     4597    public void registerObj(IUnknown obj)
     4598    {
     4599        ManagedObjRef ref = new ManagedObjRef(obj);
     4600
     4601        ManagedObj mgrobj = map.get(obj.getWrapped());
     4602        if (mgrobj != null)
     4603        {
     4604            mgrobj.addObject(ref);
     4605        }
     4606        else
     4607        {
     4608            /* Create new. */
     4609            mgrobj = new ManagedObj(obj.getWrapped());
     4610            mgrobj.addObject(ref);
     4611            map.put(obj.getWrapped(), mgrobj);
     4612        }
     4613    }
     4614
     4615    /**
     4616     * Removes a garbage collected object reference from our reference manager.
     4617     *
     4618     * Returns the server side object wrapper if there is no stub referencing it
     4619     * anymore otherwise null is returned.
     4620     */
     4621    public ManagedObj unregisterObj(ManagedObjRef objRef)
     4622    {
     4623        assert lock.isWriteLockedByCurrentThread();
     4624
     4625        ManagedObj obj = this.map.get(objRef.objId);
     4626
     4627        assert obj != null;
     4628        obj.removeObject(objRef);
     4629        if (!obj.isReferenced())
     4630            return obj;
     4631
     4632        return null;
     4633    }
     4634
     4635    public void releaseRemoteObj(ManagedObj obj)
     4636    {
     4637        if (!obj.isReferenced())
     4638        {
     4639            try
     4640            {
     4641                this.port.iManagedObjectRefRelease(obj.objId);
     4642            }
     4643            catch (InvalidObjectFaultMsg e)
     4644            {
     4645                throw new WebServiceException(e);
     4646            }
     4647            catch (RuntimeFaultMsg e)
     4648            {
     4649                throw new WebServiceException(e);
     4650            }
     4651            finally
     4652            {
     4653                this.map.remove(obj.objId);
     4654            }
     4655        }
     4656    }
     4657
     4658    /**
     4659     * An object which is living on the server side. This can be referenced
     4660     * by multiple stub objects here.
     4661     */
     4662    static class ManagedObj
     4663    {
     4664        private final String                               objId;
     4665        private final ConcurrentLinkedQueue<ManagedObjRef> refQ;
     4666
     4667        ManagedObj(String objId)
     4668        {
     4669          this.objId = objId;
     4670          this.refQ  = new ConcurrentLinkedQueue<ManagedObjRef>();
     4671        }
     4672
     4673        public void addObject(ManagedObjRef obj)
     4674        {
     4675            this.refQ.add(obj);
     4676        }
     4677
     4678        public void removeObject(ManagedObjRef obj)
     4679        {
     4680            this.refQ.remove(obj);
     4681        }
     4682
     4683        public boolean isReferenced()
     4684        {
     4685            return !this.refQ.isEmpty();
     4686        }
     4687    }
     4688
     4689    /**
     4690     * A private class extending WeakReference to get notified about garbage
     4691     * collected stub objects.
     4692     */
     4693    static class ManagedObjRef extends WeakReference<IUnknown>
     4694    {
     4695        final String objId;
     4696
     4697        ManagedObjRef(IUnknown obj)
     4698        {
     4699            super(obj, refQ);
     4700            this.objId = obj.getWrapped();
     4701        }
     4702    }
     4703
     4704    /**
     4705     * A private class implementing a thread getting notified
     4706     * about garbage collected objects so it can release the object on the
     4707     * server side if it is not used anymore.
     4708     */
     4709    static class ObjRefMgrCleanupThread extends Thread
     4710    {
     4711        ObjectRefManager            objRefMgr;
     4712        int                         cStubsReleased;
     4713        int                         cStubsReleaseThreshold;
     4714        HashMap<String, ManagedObj> mapToRelease = new HashMap<String, ManagedObj>();
     4715
     4716        ObjRefMgrCleanupThread(ObjectRefManager objRefMgr)
     4717        {
     4718            init(objRefMgr, 500);
     4719        }
     4720
     4721        ObjRefMgrCleanupThread(ObjectRefManager objRefMgr, int cStubsReleaseThreshold)
     4722        {
     4723            init(objRefMgr, cStubsReleaseThreshold);
     4724        }
     4725
     4726        private void init(ObjectRefManager objRefMgr, int cStubsReleaseThreshold)
     4727        {
     4728            this.objRefMgr = objRefMgr;
     4729            this.cStubsReleased = 0;
     4730            this.cStubsReleaseThreshold = cStubsReleaseThreshold;
     4731            setName("ObjectRefManager-VBoxWSObjRefGcThrd");
     4732            /*
     4733             * setDaemon() makes sure the jvm exits and is not blocked
     4734             * if the thread is still running so we don't have to care about
     4735             * tearing it down.
     4736             */
     4737            setDaemon(true);
     4738        }
     4739
     4740        public void run()
     4741        {
     4742            while (true)
     4743            {
     4744                while (cStubsReleased < cStubsReleaseThreshold)
     4745                {
     4746                    try
     4747                    {
     4748                        ManagedObjRef ref = (ManagedObjRef)refQ.remove();
     4749
     4750                        /* Accumulate a few objects before we start. */
     4751                        while (cStubsReleased < cStubsReleaseThreshold)
     4752                        {
     4753                            ManagedObj obj = this.objRefMgr.unregisterObj(ref);
     4754                            /*
     4755                             * If the server side object is not referenced anymore
     4756                             * promote to map for releasing later.
     4757                             */
     4758                            if (obj != null && !mapToRelease.containsKey(ref.objId))
     4759                                mapToRelease.put(ref.objId, obj);
     4760
     4761                            cStubsReleased++;
     4762                            ref = (ManagedObjRef)refQ.remove();
     4763                        }
     4764                    }
     4765                    catch (InterruptedException e)
     4766                    { /* ignore */ }
     4767                    catch (javax.xml.ws.WebServiceException e)
     4768                    { /* ignore */ }
     4769                }
     4770
     4771                /*
     4772                 * After we released enough stubs we go over all non referenced
     4773                 * server side objects and release them if they were not
     4774                 * referenced again in between.
     4775                 */
     4776                cStubsReleased = 0;
     4777                if (!mapToRelease.isEmpty())
     4778                {
     4779                    this.objRefMgr.startObjRelease();
     4780                    try
     4781                    {
     4782                        Iterator<ManagedObj> it = mapToRelease.values().iterator();
     4783                        while (it.hasNext())
     4784                        {
     4785                            ManagedObj obj = it.next();
     4786                            this.objRefMgr.releaseRemoteObj(obj);
     4787                        }
     4788
     4789                        mapToRelease.clear();
     4790                    }
     4791                    catch (javax.xml.ws.WebServiceException e)
     4792                    { /* ignore */ }
     4793                    finally
     4794                    {
     4795                        this.objRefMgr.endObjRelease();
     4796                    }
     4797                }
     4798            }
     4799        }
     4800    }
     4801}
     4802
    44264803class VBoxTLSSocketFactory extends SSLSocketFactory
    44274804{
     
    45234900
    45244901    private IVirtualBox vbox;
     4902    private ObjectRefManager objMgr;
    45254903
    45264904    private VirtualBoxManager()
     
    45394917    {
    45404918        this.port = pool.getPort();
     4919        this.objMgr = new ObjectRefManager(this.port);
    45414920        try
    45424921        {
     
    45594938
    45604939            String handle = port.iWebsessionManagerLogon(username, passwd);
    4561             this.vbox = new IVirtualBox(handle, port);
     4940            this.vbox = new IVirtualBox(handle, this.objMgr, port);
    45624941        }
    45634942        catch (Throwable t)
     
    45694948            }
    45704949            // we have to throw smth derived from RuntimeException
    4571             throw new VBoxException(t.getMessage(), t, this.port);
     4950            throw new VBoxException(t.getMessage(), t, this.objMgr, this.port);
    45724951        }
    45734952    }
     
    45774956    {
    45784957        this.port = pool.getPort();
     4958        this.objMgr = new ObjectRefManager(this.port);
    45794959
    45804960        try
     
    45904970                put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, url);
    45914971            String handle = port.iWebsessionManagerLogon(username, passwd);
    4592             this.vbox = new IVirtualBox(handle, port);
     4972            this.vbox = new IVirtualBox(handle, this.objMgr, port);
    45934973        }
    45944974        catch (Throwable t)
     
    46004980            }
    46014981            // we have to throw smth derived from RuntimeException
    4602             throw new VBoxException(t.getMessage(), t, this.port);
     4982            throw new VBoxException(t.getMessage(), t, this.objMgr, this.port);
    46034983        }
    46044984    }
     
    46164996        catch (InvalidObjectFaultMsg e)
    46174997        {
    4618             throw new VBoxException(e.getMessage(), e, this.port);
     4998            throw new VBoxException(e.getMessage(), e, this.objMgr, this.port);
    46194999        }
    46205000        catch (RuntimeFaultMsg e)
    46215001        {
    4622             throw new VBoxException(e.getMessage(), e, this.port);
     5002            throw new VBoxException(e.getMessage(), e, this.objMgr, this.port);
    46235003        }
    46245004        finally
     
    46515031        {
    46525032            String handle = port.iWebsessionManagerGetSessionObject(this.vbox.getWrapped());
    4653             return new ISession(handle, port);
     5033            return new ISession(handle, this.objMgr, port);
    46545034        }
    46555035        catch (InvalidObjectFaultMsg e)
    46565036        {
    4657             throw new VBoxException(e.getMessage(), e, this.port);
     5037            throw new VBoxException(e.getMessage(), e, this.objMgr, this.port);
    46585038        }
    46595039        catch (RuntimeFaultMsg e)
    46605040        {
    4661             throw new VBoxException(e.getMessage(), e, this.port);
     5041            throw new VBoxException(e.getMessage(), e, this.objMgr, this.port);
    46625042        }
    46635043    }
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette