<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<!DOCTYPE bugzilla SYSTEM "https://bugs.webkit.org/page.cgi?id=bugzilla.dtd">

<bugzilla version="5.0.4.1"
          urlbase="https://bugs.webkit.org/"
          
          maintainer="admin@webkit.org"
>

    <bug>
          <bug_id>31633</bug_id>
          
          <creation_ts>2009-11-18 12:12:52 -0800</creation_ts>
          <short_desc>Need to ensure that Document::postTask does not provide the Task with a dangling pointer to destroyed Document</short_desc>
          <delta_ts>2010-01-15 13:53:07 -0800</delta_ts>
          <reporter_accessible>1</reporter_accessible>
          <cclist_accessible>1</cclist_accessible>
          <classification_id>1</classification_id>
          <classification>Unclassified</classification>
          <product>WebKit</product>
          <component>WebCore Misc.</component>
          <version>528+ (Nightly build)</version>
          <rep_platform>All</rep_platform>
          <op_sys>All</op_sys>
          <bug_status>RESOLVED</bug_status>
          <resolution>FIXED</resolution>
          
          
          <bug_file_loc></bug_file_loc>
          <status_whiteboard></status_whiteboard>
          <keywords></keywords>
          <priority>P2</priority>
          <bug_severity>Normal</bug_severity>
          <target_milestone>---</target_milestone>
          
          
          <everconfirmed>1</everconfirmed>
          <reporter name="Dmitry Titov">dimich</reporter>
          <assigned_to name="Dmitry Titov">dimich</assigned_to>
          <cc>ap</cc>
    
    <cc>atwilson</cc>
    
    <cc>darin</cc>
    
    <cc>levin</cc>
          

      

      

      

          <comment_sort_order>oldest_to_newest</comment_sort_order>  
          <long_desc isprivate="0" >
    <commentid>164652</commentid>
    <comment_count>0</comment_count>
    <who name="Dmitry Titov">dimich</who>
    <bug_when>2009-11-18 12:12:52 -0800</bug_when>
    <thetext>Based on a discussion in bug 31615, the Document::postTask, when posting a Task from non-main thread, relies on a Document still be alive when the Task is dispatched on the main thread. This was true for dedicated workers but since then we have shared workers that can outlive a document while using it for loading (XHR and importScripts).

It might be that because of serialization of all actions through main run loop we don&apos;t have much troubles right now, but this can be more of a happy accident. Need to review the design.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>168877</commentid>
    <comment_count>1</comment_count>
    <who name="Andrew Wilson">atwilson</who>
    <bug_when>2009-12-04 12:49:19 -0800</bug_when>
    <thetext>BTW, the situation is worse for dedicated workers than it is for SharedWorkers.

Closing a document causes a message to be sent to dedicated workers telling them to shut down, but they can still initiate Document::postTask() calls while that message floats around in the queue.

SharedWorkers can &quot;outlive&quot; their initial parent document, but once the document is detached the reference to it is removed from the SharedWorkerRepository, and so no further postTask() invocations can be sent to it. So the Document code has to handle messages that are already enqueued, but no more messages will be enqueued after the fact.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>168900</commentid>
    <comment_count>2</comment_count>
    <who name="Alexey Proskuryakov">ap</who>
    <bug_when>2009-12-04 13:10:39 -0800</bug_when>
    <thetext>As discussed in bug 31615, worker messaging proxy is supposed to keep the document alive for as long as there can still be messages coming from dedicated workers.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>168910</commentid>
    <comment_count>3</comment_count>
    <who name="Andrew Wilson">atwilson</who>
    <bug_when>2009-12-04 13:34:34 -0800</bug_when>
    <thetext>Agreed, so we should be good with dedicated workers.

Following up with a bit more detail on my previous response - Document::detach() calls SharedWorkerRepository::documentDetached(), so the end result is that Documents are guaranteed not to receive any further tasks from SharedWorkers after Document::detach() exits.

However, there doesn&apos;t seem to be anything preventing the Document from being freed immediately after Document.detach() is called (I think) - FrameLoader::clear() invokes document-&gt;detach(), then shortly thereafter invokes m_frame-&gt;setDocument(0) which seems like it could free the document.

I know lots of ideas have been kicked around for this, but I&apos;ll throw another
one out there:

1) State that it&apos;s illegal to call Document.postTask() after Document.detach()
is invoked, and add an assertion to Document.postTask() to enforce this (possibly just in the &quot;not called from the main thread&quot; case).

2) At the end of Document.detach(), invoke Document::addRef() to increase the
ref count, then invoke postTask() to execute a task to decrement the ref count.
This ensures that any pending tasks for that Document get dispatched before the Document goes away.

Alternatively, we could get rid of #1 and push the code for #2 into
SharedWorkerRepository::documentDetached(), thereby making the worker code
itself responsible for keeping the Document alive until any pending x-thread
tasks have been dispatched. I actually think that&apos;s probably the simplest
solution, and is more in line with what we already do for dedicated workers.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>168926</commentid>
    <comment_count>4</comment_count>
    <who name="Alexey Proskuryakov">ap</who>
    <bug_when>2009-12-04 14:15:27 -0800</bug_when>
    <thetext>I have some difficulty understanding the proposal.

&gt; 1) State that it&apos;s illegal to call Document.postTask() after Document.detach()
&gt; is invoked,

Is it correct that these methods are called from different threads? How can one thread make another not do something, other than by posting a message to that effect? How will it know when the message has been received, processed, and taken effect?

Enforcing behavior with assertions is good, but I&apos;d like to understand what mechanism guarantees this behavior.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>168927</commentid>
    <comment_count>5</comment_count>
    <who name="Andrew Wilson">atwilson</who>
    <bug_when>2009-12-04 14:30:57 -0800</bug_when>
    <thetext>In the case of SharedWorkers, it&apos;s inherently enforced that Document-&gt;postTask() is only called while holding a mutex that is also grabbed by SharedWorkerRepository::documentDetached() (there&apos;s a similar thing happening with MessagePorts with an internal mutex). So you don&apos;t have to send a message - merely have an internal reference which is cleared/accessed via a mutex, which we currently do have.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>168946</commentid>
    <comment_count>6</comment_count>
    <who name="Alexey Proskuryakov">ap</who>
    <bug_when>2009-12-04 15:11:37 -0800</bug_when>
    <thetext>In the case of dedicated workers, I&apos;m finding comfort in the fact that we can switch to a lock-free queue if we need to.

It seems unfortunate that shared workers need a high level mutex that affects both queues and other code. Maybe that&apos;s the only way to implement them, though.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>168957</commentid>
    <comment_count>7</comment_count>
    <who name="Andrew Wilson">atwilson</who>
    <bug_when>2009-12-04 15:26:09 -0800</bug_when>
    <thetext>Given that shared workers only communicate with the parent thread in order to coordinate network access, worker startup and document shutdown, I think the overhead of a mutex is negligible compared to the frequency/cost of those operations.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>179041</commentid>
    <comment_count>8</comment_count>
    <who name="Dmitry Titov">dimich</who>
    <bug_when>2010-01-09 14:23:57 -0800</bug_when>
    <thetext>Perhaps a solution that is more generic and does not rely on analysis of actual codepath for each use case could be more reliable. Other parts of WebKit code will eventually use ScriptExecutionContext::postTask() and the authors of that code might be unaware of the necessary conditions under which this API is safe. Database in Workers (bug 22725) is one example of code that will likely use it.

Andrew and I discussed potential solutions lately. The one we think is promising is along these lines:

- Have a thread-safe-ref-counted class that keeps a raw pointer to a Document (lets call it DocumentWeakRef). 
- Keep a RefPtr to it from Document. The DocumentWeakRef is created on demand and then never replaced for a given Document.
- Give RefPtr to DocumentWeakRef to each Task.
- When Document dies, it nullifies the pointer to itself inside DocumentWeakRef.
- When Task comes from queues to be executed, if the document pointer in DocumentWeakRef is 0, it does not call Task::performTask(document).

It adds a thread-safe refcount per task creation/destruction. On the other hand, it is only needed for cases when non-main thread posts a task to a Document. For example, posting a message to a Worker is safe because Workers control their run loop.

If this sounds good in general, I&apos;ll create a patch.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>179102</commentid>
    <comment_count>9</comment_count>
    <who name="Darin Adler">darin</who>
    <bug_when>2010-01-09 18:47:07 -0800</bug_when>
    <thetext>The design you describe is quite similar to the way nodes used to point to documents. It&apos;s more efficient for document destruction than a design where we have to keep track of multiple weak document pointers and null out each of one of them, and I like that.

We need to be sure that people only read and write the document pointer in one of these handles (DocumentWeakRef objects) on a single thread, the same one where it&apos;s legal to ref/deref and destroy documents, so I&apos;d like to see assertions that check that.

Other than that, I can&apos;t think of any obvious disadvantages. Lets do it.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>180495</commentid>
    <comment_count>10</comment_count>
      <attachid>46531</attachid>
    <who name="Dmitry Titov">dimich</who>
    <bug_when>2010-01-13 18:04:33 -0800</bug_when>
    <thetext>Created attachment 46531
Patch.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>180816</commentid>
    <comment_count>11</comment_count>
      <attachid>46531</attachid>
    <who name="Darin Adler">darin</who>
    <bug_when>2010-01-14 11:25:19 -0800</bug_when>
    <thetext>Comment on attachment 46531
Patch.

&gt; +DocumentWeakReference::DocumentWeakReference(Document* doc)
&gt; +    : m_document(doc)
&gt; +{
&gt; +    ASSERT(isMainThread());
&gt; +}
&gt; +
&gt; +Document* DocumentWeakReference::document()
&gt; +{
&gt; +    ASSERT(isMainThread());
&gt; +    return m_document;
&gt; +}
&gt; +
&gt; +void DocumentWeakReference::clear()
&gt; +{
&gt; +    ASSERT(isMainThread());
&gt; +    m_document = 0;
&gt; +}

These super-short functions seem like they ought to be inlined, unless there is a reason not to. If they are only used within this file, then I suggest just marking them inline. If they are used elsewhere we could consider putting them in the header. Perhaps it&apos;s the main thread bit that can&apos;t be easily be put in the header?

It&apos;s a bit strange to have this class&apos;s function definitions appear in the file above the definition of the global variable, documentsThatNeedStyleRecalc. I&apos;d prefer they be further down. Maybe even at the end of the file instead of the start.

Argument name should be &quot;document&quot;, not &quot;doc&quot;.

&gt; +    if (m_weakReference)
&gt; +        m_weakReference-&gt;clear();

No need for the null check here.

&gt; +    PerformTaskContext(PassRefPtr&lt;DocumentWeakReference&gt; documentWeakRef, PassOwnPtr&lt;ScriptExecutionContext::Task&gt; task)
&gt; +        : documentWeakRef(documentWeakRef)
&gt;          , task(task)
&gt;      {
&gt;      }

I suggest naming the argument &quot;document&quot; or &quot;documentReference&quot; instead of documentWeakRef.

&gt; +    RefPtr&lt;DocumentWeakReference&gt; documentWeakRef;

I think you should name data member &quot;document&quot; or &quot;documentReference&quot;; no need to repeat the word &quot;weak&quot; or to abbreviate &quot;reference&quot;.

&gt; +    if (Document* doc = ptctx-&gt;documentWeakRef-&gt;document())
&gt; +        ptctx-&gt;task-&gt;performTask(doc);

Please use the name &quot;document&quot; instead of &quot;doc&quot; here for the local variable.

I also wise the variable &quot;ptctx&quot; was instead named &quot;context&quot;.

&gt; +        ASSERT(m_weakReference);
&gt; +        callOnMainThread(performTask, new PerformTaskContext(m_weakReference, task));

I don&apos;t think you need this assertion.

&gt; +    static PassRefPtr&lt;DocumentWeakReference&gt; create(Document* doc)
&gt; +    {
&gt; +        return adoptRef(new DocumentWeakReference(doc));
&gt; +    }

Please use the argument name &quot;document&quot; instead of &quot;doc&quot;.

I&apos;m going to say review+ because all my comments are essentially stylistic ones; please consider addressing them anyway. I&apos;m disappointed we can&apos;t test it!</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>180817</commentid>
    <comment_count>12</comment_count>
      <attachid>46531</attachid>
    <who name="Darin Adler">darin</who>
    <bug_when>2010-01-14 11:26:15 -0800</bug_when>
    <thetext>Comment on attachment 46531
Patch.

Is it always OK to not call the task at all if the document is 0? What if the task needs to deallocate some memory or something? Maybe instead we should call with Document* of 0 and have the tasks handle that case?</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>180978</commentid>
    <comment_count>13</comment_count>
    <who name="Dmitry Titov">dimich</who>
    <bug_when>2010-01-14 15:56:18 -0800</bug_when>
    <thetext>(In reply to comment #12)
&gt; (From update of attachment 46531 [details])
&gt; Is it always OK to not call the task at all if the document is 0? What if the
&gt; task needs to deallocate some memory or something? Maybe instead we should call
&gt; with Document* of 0 and have the tasks handle that case?

I was thinking about having another virtual method, like &apos;doCleanup()&apos; that would be always called after performTask(document), or alone if the document is 0. This way, even if document is 0 there is always a method to be called and do document-independent things. The reason I didn&apos;t add it was that I didn&apos;t find a case where it would be actually needed.

Maybe later if we find a case which needs it?</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>181261</commentid>
    <comment_count>14</comment_count>
    <who name="Andrew Wilson">atwilson</who>
    <bug_when>2010-01-15 10:03:32 -0800</bug_when>
    <thetext>(In reply to comment #12)
&gt; (From update of attachment 46531 [details])
&gt; Is it always OK to not call the task at all if the document is 0? What if the
&gt; task needs to deallocate some memory or something? 

Tasks can use their destructor for this (and most do, via instance members of type RefPtr, etc). Seems more fragile to pass in a null document pointer (so a poorly written performTask() handler crashes the browser) than it would be to just leak memory.

I don&apos;t think that an explicit doCleanup() function is necessary. If an instance really needed to know that performTask() was not called, they could easily accomplish this with a boolean and a check in their destructor.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>181291</commentid>
    <comment_count>15</comment_count>
    <who name="Darin Adler">darin</who>
    <bug_when>2010-01-15 11:34:42 -0800</bug_when>
    <thetext>(In reply to comment #14)
&gt; Tasks can use their destructor for this (and most do, via instance members of
&gt; type RefPtr, etc).

Good answer.

&gt; Seems more fragile to pass in a null document pointer (so a
&gt; poorly written performTask() handler crashes the browser) than it would be to
&gt; just leak memory.

I don’t agree with this sentence, but it doesn’t matter. The first sentence was sufficient to convince me the design is good.</thetext>
  </long_desc><long_desc isprivate="0" >
    <commentid>181370</commentid>
    <comment_count>16</comment_count>
    <who name="Dmitry Titov">dimich</who>
    <bug_when>2010-01-15 13:53:07 -0800</bug_when>
    <thetext>Fixed all the style issues Darin suggested.

Landed: http://trac.webkit.org/changeset/53345</thetext>
  </long_desc>
      
          <attachment
              isobsolete="0"
              ispatch="1"
              isprivate="0"
          >
            <attachid>46531</attachid>
            <date>2010-01-13 18:04:33 -0800</date>
            <delta_ts>2010-01-14 11:26:15 -0800</delta_ts>
            <desc>Patch.</desc>
            <filename>patch.txt</filename>
            <type>text/plain</type>
            <size>5041</size>
            <attacher name="Dmitry Titov">dimich</attacher>
            
              <data encoding="base64">ZGlmZiAtLWdpdCBhL1dlYkNvcmUvQ2hhbmdlTG9nIGIvV2ViQ29yZS9DaGFuZ2VMb2cKaW5kZXgg
ZTQ5MDk5Yy4uZjcwYTM2MSAxMDA2NDQKLS0tIGEvV2ViQ29yZS9DaGFuZ2VMb2cKKysrIGIvV2Vi
Q29yZS9DaGFuZ2VMb2cKQEAgLTEsMyArMSwyNCBAQAorMjAxMC0wMS0xMyAgRG1pdHJ5IFRpdG92
ICA8ZGltaWNoQGNocm9taXVtLm9yZz4KKworICAgICAgICBSZXZpZXdlZCBieSBOT0JPRFkgKE9P
UFMhKS4KKworICAgICAgICBOZWVkIHRvIGVuc3VyZSB0aGF0IERvY3VtZW50Ojpwb3N0VGFzayBk
b2VzIG5vdCBwcm92aWRlIHRoZSBUYXNrIHdpdGggYSBkYW5nbGluZyBwb2ludGVyIHRvIGRlc3Ry
b3llZCBEb2N1bWVudAorICAgICAgICBodHRwczovL2J1Z3Mud2Via2l0Lm9yZy9zaG93X2J1Zy5j
Z2k/aWQ9MzE2MzMKKworICAgICAgICBEb24ndCBzZWUgYSB3YXkgdG8gYWRkIHRlc3QgZm9yIGl0
LCB3ZSBkb24ndCBoYXZlIGEgd2F5IHRvIHJlcHJvZHVjZSB0aGUgaXNzdWUgY3VycmVudGx5Lgor
CisgICAgICAgICogZG9tL0RvY3VtZW50LmNwcDoKKyAgICAgICAgKFdlYkNvcmU6OkRvY3VtZW50
V2Vha1JlZmVyZW5jZTo6RG9jdW1lbnRXZWFrUmVmZXJlbmNlKToKKyAgICAgICAgKFdlYkNvcmU6
OkRvY3VtZW50V2Vha1JlZmVyZW5jZTo6ZG9jdW1lbnQpOgorICAgICAgICAoV2ViQ29yZTo6RG9j
dW1lbnRXZWFrUmVmZXJlbmNlOjpjbGVhcik6CisgICAgICAgIChXZWJDb3JlOjpEb2N1bWVudDo6
RG9jdW1lbnQpOiBDcmVhdGUgYSB3ZWFrIHJlZmVyZW5jZSB0byB0aGlzIERvY3VtZW50LgorICAg
ICAgICAoV2ViQ29yZTo6RG9jdW1lbnQ6On5Eb2N1bWVudCk6IENsZWFyIHRoZSB3ZWFrIHBvaW50
ZXIsIHByZXZlbnRpbmcgZnVydGhlciBleGVjdXRpb24gb2YgdGFza3MuCisgICAgICAgIChXZWJD
b3JlOjpQZXJmb3JtVGFza0NvbnRleHQ6OlBlcmZvcm1UYXNrQ29udGV4dCk6CisgICAgICAgIChX
ZWJDb3JlOjpwZXJmb3JtVGFzayk6IENoZWNrIGlmIHRoZSBkb2N1bWVudFdlYWtSZWZlcmVuY2Ug
aXMgY2xlYXJlZCBieSBEb2N1bWVudCBkZXN0cnVjdG9yIC0gaW4gdGhpcyBjYXNlIGRvIG5vdCBy
dW4gdGhlIHRhc2suCisgICAgICAgIChXZWJDb3JlOjpEb2N1bWVudDo6cG9zdFRhc2spOgorICAg
ICAgICAqIGRvbS9Eb2N1bWVudC5oOgorICAgICAgICAoV2ViQ29yZTo6RG9jdW1lbnRXZWFrUmVm
ZXJlbmNlOjpjcmVhdGUpOgorCiAyMDEwLTAxLTExICBOaWtvbGFzIFppbW1lcm1hbm4gIDxuemlt
bWVybWFubkByaW0uY29tPgogCiAgICAgICAgIE5vdCByZXZpZXdlZC4gQXR0ZW1wdCB0byBmaXgg
d2luZG93cyBidWlsZHMsIGJ5IHJlbW92aW5nIHRoZSBuby1sb25nZXIgZXhpc3RhbnQgSlNTVkdQ
b2ludExpc3RDdXN0b20uY3BwIGZyb20gSlNCaW5kaW5nc0FsbEluT25lLmNwcC4KZGlmZiAtLWdp
dCBhL1dlYkNvcmUvZG9tL0RvY3VtZW50LmNwcCBiL1dlYkNvcmUvZG9tL0RvY3VtZW50LmNwcApp
bmRleCAzNzYzNWY4Li5iYWNiMTNkIDEwMDY0NAotLS0gYS9XZWJDb3JlL2RvbS9Eb2N1bWVudC5j
cHAKKysrIGIvV2ViQ29yZS9kb20vRG9jdW1lbnQuY3BwCkBAIC0zMTUsNiArMzE1LDI1IEBAIHN0
YXRpYyBib29sIGRpc2FibGVSYW5nZU11dGF0aW9uKFBhZ2UqIHBhZ2UpCiAjZW5kaWYKIH0KIAor
CitEb2N1bWVudFdlYWtSZWZlcmVuY2U6OkRvY3VtZW50V2Vha1JlZmVyZW5jZShEb2N1bWVudCog
ZG9jKQorICAgIDogbV9kb2N1bWVudChkb2MpCit7CisgICAgQVNTRVJUKGlzTWFpblRocmVhZCgp
KTsKK30KKworRG9jdW1lbnQqIERvY3VtZW50V2Vha1JlZmVyZW5jZTo6ZG9jdW1lbnQoKQorewor
ICAgIEFTU0VSVChpc01haW5UaHJlYWQoKSk7CisgICAgcmV0dXJuIG1fZG9jdW1lbnQ7Cit9CisK
K3ZvaWQgRG9jdW1lbnRXZWFrUmVmZXJlbmNlOjpjbGVhcigpCit7CisgICAgQVNTRVJUKGlzTWFp
blRocmVhZCgpKTsKKyAgICBtX2RvY3VtZW50ID0gMDsKK30KKwogc3RhdGljIEhhc2hTZXQ8RG9j
dW1lbnQqPiogZG9jdW1lbnRzVGhhdE5lZWRTdHlsZVJlY2FsYyA9IDA7CiAKIERvY3VtZW50OjpE
b2N1bWVudChGcmFtZSogZnJhbWUsIGJvb2wgaXNYSFRNTCkKQEAgLTM2MCw2ICszNzksNyBAQCBE
b2N1bWVudDo6RG9jdW1lbnQoRnJhbWUqIGZyYW1lLCBib29sIGlzWEhUTUwpCiAjaWYgRU5BQkxF
KFdNTCkKICAgICAsIG1fY29udGFpbnNXTUxDb250ZW50KGZhbHNlKQogI2VuZGlmCisgICAgLCBt
X3dlYWtSZWZlcmVuY2UoRG9jdW1lbnRXZWFrUmVmZXJlbmNlOjpjcmVhdGUodGhpcykpCiB7CiAg
ICAgbV9kb2N1bWVudCA9IHRoaXM7CiAKQEAgLTUwOSw2ICs1MjksOSBAQCBEb2N1bWVudDo6fkRv
Y3VtZW50KCkKIAogICAgIGlmIChtX3N0eWxlU2hlZXRzKQogICAgICAgICBtX3N0eWxlU2hlZXRz
LT5kb2N1bWVudERlc3Ryb3llZCgpOworCisgICAgaWYgKG1fd2Vha1JlZmVyZW5jZSkKKyAgICAg
ICAgbV93ZWFrUmVmZXJlbmNlLT5jbGVhcigpOwogfQogCiAjaWYgVVNFKEpTQykKQEAgLTQ2ODEs
MjAgKzQ3MDQsMjYgQEAgcHJpdmF0ZToKIH07CiAKIHN0cnVjdCBQZXJmb3JtVGFza0NvbnRleHQg
OiBOb25jb3B5YWJsZSB7Ci0gICAgUGVyZm9ybVRhc2tDb250ZXh0KFNjcmlwdEV4ZWN1dGlvbkNv
bnRleHQqIHNjcmlwdEV4ZWN1dGlvbkNvbnRleHQsIFBhc3NPd25QdHI8U2NyaXB0RXhlY3V0aW9u
Q29udGV4dDo6VGFzaz4gdGFzaykKLSAgICAgICAgOiBzY3JpcHRFeGVjdXRpb25Db250ZXh0KHNj
cmlwdEV4ZWN1dGlvbkNvbnRleHQpCisgICAgUGVyZm9ybVRhc2tDb250ZXh0KFBhc3NSZWZQdHI8
RG9jdW1lbnRXZWFrUmVmZXJlbmNlPiBkb2N1bWVudFdlYWtSZWYsIFBhc3NPd25QdHI8U2NyaXB0
RXhlY3V0aW9uQ29udGV4dDo6VGFzaz4gdGFzaykKKyAgICAgICAgOiBkb2N1bWVudFdlYWtSZWYo
ZG9jdW1lbnRXZWFrUmVmKQogICAgICAgICAsIHRhc2sodGFzaykKICAgICB7CiAgICAgfQogCi0g
ICAgU2NyaXB0RXhlY3V0aW9uQ29udGV4dCogc2NyaXB0RXhlY3V0aW9uQ29udGV4dDsgLy8gVGhl
IGNvbnRleHQgc2hvdWxkIGV4aXN0IHVudGlsIHRhc2sgZXhlY3V0aW9uLgorICAgIFJlZlB0cjxE
b2N1bWVudFdlYWtSZWZlcmVuY2U+IGRvY3VtZW50V2Vha1JlZjsKICAgICBPd25QdHI8U2NyaXB0
RXhlY3V0aW9uQ29udGV4dDo6VGFzaz4gdGFzazsKIH07CiAKIHN0YXRpYyB2b2lkIHBlcmZvcm1U
YXNrKHZvaWQqIGN0eCkKIHsKKyAgICBBU1NFUlQoaXNNYWluVGhyZWFkKCkpOworCiAgICAgUGVy
Zm9ybVRhc2tDb250ZXh0KiBwdGN0eCA9IHJlaW50ZXJwcmV0X2Nhc3Q8UGVyZm9ybVRhc2tDb250
ZXh0Kj4oY3R4KTsKLSAgICBwdGN0eC0+dGFzay0+cGVyZm9ybVRhc2socHRjdHgtPnNjcmlwdEV4
ZWN1dGlvbkNvbnRleHQpOworICAgIEFTU0VSVChwdGN0eCk7CisKKyAgICBpZiAoRG9jdW1lbnQq
IGRvYyA9IHB0Y3R4LT5kb2N1bWVudFdlYWtSZWYtPmRvY3VtZW50KCkpCisgICAgICAgIHB0Y3R4
LT50YXNrLT5wZXJmb3JtVGFzayhkb2MpOworCiAgICAgZGVsZXRlIHB0Y3R4OwogfQogCkBAIC00
NzA0LDcgKzQ3MzMsOCBAQCB2b2lkIERvY3VtZW50Ojpwb3N0VGFzayhQYXNzT3duUHRyPFRhc2s+
IHRhc2spCiAgICAgICAgIFNjcmlwdEV4ZWN1dGlvbkNvbnRleHRUYXNrVGltZXIqIHRpbWVyID0g
bmV3IFNjcmlwdEV4ZWN1dGlvbkNvbnRleHRUYXNrVGltZXIoc3RhdGljX2Nhc3Q8RG9jdW1lbnQq
Pih0aGlzKSwgdGFzayk7CiAgICAgICAgIHRpbWVyLT5zdGFydE9uZVNob3QoMCk7CiAgICAgfSBl
bHNlIHsKLSAgICAgICAgY2FsbE9uTWFpblRocmVhZChwZXJmb3JtVGFzaywgbmV3IFBlcmZvcm1U
YXNrQ29udGV4dCh0aGlzLCB0YXNrKSk7CisgICAgICAgIEFTU0VSVChtX3dlYWtSZWZlcmVuY2Up
OworICAgICAgICBjYWxsT25NYWluVGhyZWFkKHBlcmZvcm1UYXNrLCBuZXcgUGVyZm9ybVRhc2tD
b250ZXh0KG1fd2Vha1JlZmVyZW5jZSwgdGFzaykpOwogICAgIH0KIH0KIApkaWZmIC0tZ2l0IGEv
V2ViQ29yZS9kb20vRG9jdW1lbnQuaCBiL1dlYkNvcmUvZG9tL0RvY3VtZW50LmgKaW5kZXggYzcx
ZTgwZi4uNDMwYTBhZCAxMDA2NDQKLS0tIGEvV2ViQ29yZS9kb20vRG9jdW1lbnQuaAorKysgYi9X
ZWJDb3JlL2RvbS9Eb2N1bWVudC5oCkBAIC0xNzMsNiArMTczLDE5IEBAIHN0cnVjdCBGb3JtRWxl
bWVudEtleUhhc2hUcmFpdHMgOiBXVEY6OkdlbmVyaWNIYXNoVHJhaXRzPEZvcm1FbGVtZW50S2V5
PiB7CiAgICAgc3RhdGljIGJvb2wgaXNEZWxldGVkVmFsdWUoY29uc3QgRm9ybUVsZW1lbnRLZXkm
IHZhbHVlKSB7IHJldHVybiB2YWx1ZS5pc0hhc2hUYWJsZURlbGV0ZWRWYWx1ZSgpOyB9CiB9Owog
CitjbGFzcyBEb2N1bWVudFdlYWtSZWZlcmVuY2UgOiBwdWJsaWMgVGhyZWFkU2FmZVNoYXJlZDxE
b2N1bWVudFdlYWtSZWZlcmVuY2U+IHsKK3B1YmxpYzoKKyAgICBzdGF0aWMgUGFzc1JlZlB0cjxE
b2N1bWVudFdlYWtSZWZlcmVuY2U+IGNyZWF0ZShEb2N1bWVudCogZG9jKQorICAgIHsKKyAgICAg
ICAgcmV0dXJuIGFkb3B0UmVmKG5ldyBEb2N1bWVudFdlYWtSZWZlcmVuY2UoZG9jKSk7CisgICAg
fQorICAgIERvY3VtZW50KiBkb2N1bWVudCgpOworICAgIHZvaWQgY2xlYXIoKTsKK3ByaXZhdGU6
CisgICAgRG9jdW1lbnRXZWFrUmVmZXJlbmNlKERvY3VtZW50Kik7CisgICAgRG9jdW1lbnQqIG1f
ZG9jdW1lbnQ7Cit9OworCiBjbGFzcyBEb2N1bWVudCA6IHB1YmxpYyBDb250YWluZXJOb2RlLCBw
dWJsaWMgU2NyaXB0RXhlY3V0aW9uQ29udGV4dCB7CiBwdWJsaWM6CiAgICAgc3RhdGljIFBhc3NS
ZWZQdHI8RG9jdW1lbnQ+IGNyZWF0ZShGcmFtZSogZnJhbWUpCkBAIC0xMTk1LDYgKzEyMDgsOCBA
QCBwcml2YXRlOgogI2lmIEVOQUJMRShXTUwpCiAgICAgYm9vbCBtX2NvbnRhaW5zV01MQ29udGVu
dDsKICNlbmRpZgorCisgICAgUmVmUHRyPERvY3VtZW50V2Vha1JlZmVyZW5jZT4gbV93ZWFrUmVm
ZXJlbmNlOwogfTsKIAogaW5saW5lIGJvb2wgRG9jdW1lbnQ6Omhhc0VsZW1lbnRXaXRoSWQoQXRv
bWljU3RyaW5nSW1wbCogaWQpIGNvbnN0Cg==
</data>
<flag name="review"
          id="28815"
          type_id="1"
          status="+"
          setter="darin"
    />
    <flag name="commit-queue"
          id="28816"
          type_id="3"
          status="-"
          setter="dimich"
    />
          </attachment>
      

    </bug>

</bugzilla>