Bug 476444 - Buffers overhaul
Summary: Buffers overhaul
Status: RESOLVED FIXED
Alias: None
Product: Handly
Classification: Technology
Component: Core (show other bugs)
Version: 0.4   Edit
Hardware: All All
: P3 enhancement
Target Milestone: 0.4   Edit
Assignee: Vladimir Piskarev CLA
QA Contact:
URL:
Whiteboard: breakingchange
Keywords: api
Depends on:
Blocks:
 
Reported: 2015-09-02 09:54 EDT by Vladimir Piskarev CLA
Modified: 2015-09-23 07:22 EDT (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Vladimir Piskarev CLA 2015-09-02 09:54:47 EDT
This is a follow-up to bug 476031.

Rename PrivateBuffer to ChildBuffer and make it thread-safe. Also, extract a SimpleBuffer and clarify some of the buffer-related Javadocs.
Comment 2 Vladimir Piskarev CLA 2015-09-09 08:22:09 EDT
Reopened to introduce the notion of multiple independent ownership of the buffer, manifested in the new addRef()/release() methods in IBuffer. The existing dispose() method becomes an alias to release() and is to be deprecated.

The new ownership model is introduced in part to address an exception safety concern with regard to construction of buffers that need to own a given "underlying" buffer. For example, the following idiom currently used in the Handly code base is NOT exception safe:

IBuffer delegate = sourceFile.getBuffer();
// delegate ownership is transferred to the working copy buffer
IBuffer buffer = new DelegatingWorkingCopyBuffer(delegate,
    getWorkingCopyReconciler(...));
try
{
    sourceFile.becomeWorkingCopy(buffer, ...);
}
finally
{
    buffer.dispose();
}

Should the getWorkingCopyReconciler method fail, the delegate buffer sourceFile.getBuffer() would "leak" -- it will never be closed.

Multiple ownership model lets us re-write the code in exception safe way:

IBuffer delegate = sourceFile.getBuffer();
try
{
    IBuffer buffer = new DelegatingWorkingCopyBuffer(delegate,
        getWorkincCopyReconciler()); // will addRef the delegate
    try
    {
        sourceFile.becomeWorkingCopy(buffer, ...); // will addRef the buffer
    }
    finally
    {
        buffer.release();
    }
}
finally
{
    delegate.release();
}
Comment 3 Vladimir Piskarev CLA 2015-09-09 10:37:34 EDT
Pushed to master:
http://git.eclipse.org/c/handly/org.eclipse.handly.git/commit/?id=ae73bc073814dcbc7719396352d78eab65dcfe24


ATTENTION. Significant breaking changes:

* DelegatingWorkingCopyBuffer constructor IMPORTANT CONTRACT CHANGE: the given delegate buffer is now owned independently (addRef'ed) by the working copy buffer; the client still owns the delegate and MUST ultimately release it. The prior contract was that the client transferred ownership of the delegate to the working copy buffer and no longer owned the delegate, even if the constructor threw an exception. Please see comment 2 for an example of DelegatingWorkingCopyBuffer construction before and after the contract change. PLEASE MIGRATE YOUR CODE accordingly or else the delegate buffer's leak may result in unspecified behavior.

* Same for XtextWorkingCopyBuffer.

* Multiple changes inside TextFileBuffer. All fields are now private. The following protected methods were removed: isClosed(), checkNotClosed(), createChangeOperation(IBufferChange). The class no longer overrides hashCode() and equals().

* Same for TextEditorBuffer.
Comment 4 Vladimir Piskarev CLA 2015-09-23 07:22:26 EDT
Further polish:
http://git.eclipse.org/c/handly/org.eclipse.handly.git/commit/?id=01fa163f386f3a50e037c29e4a1b6f8f74f2592c

Note that IDocumentBuffer has been deprecated with this commit. IBuffer itself can now provide the document.