qpid-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From "Chuck Rolke (JIRA)" <j...@apache.org>
Subject [jira] [Commented] (QPID-3193) .NET Binding for Messaging classes need a test to check that binding is still in effect
Date Fri, 08 Apr 2011 19:23:05 GMT

    [ https://issues.apache.org/jira/browse/QPID-3193?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=13017613#comment-13017613
] 

Chuck Rolke commented on QPID-3193:
-----------------------------------

You are correct about the IsDisposed leaving a window open. The binding objects really want
to be multithread safe so they must then do more heavy lifting.

The stackoverflow article talks about controls that have an IsDisposed property. As is, the
classes don't have such a property and this Jira is a proposal to add one. But by making each
class more thread safe with a lock and adding the dispose check then users won't need an IsDisposed
property.

{code:title=Existing Code|borderStyle=solid}
System::String ^ Message::GetContent()
{
    System::String ^ result = nullptr;
    System::Exception ^ newException = nullptr;

    try 
    {
        result = gcnew String(messagep->getContent().c_str());
    } 
    catch (const ::qpid::types::Exception & error) 
    {
        String ^ errmsg = gcnew String(error.what());
        newException    = gcnew QpidException(errmsg);
    }

    if (newException != nullptr) 	
    {
        throw newException;
    }

    return result;
}
{code}

When a user generates the AccVio C# code sees the following exception. Curiously, this exception
is not caught and rethrown by the GetContent function. It is caught directly by the C# caller
program (which I had trouble catching previously).

{noformat}
Exception System.AccessViolationException: 
  Attempted to read or write protected memory. 
  This is often an indication that other memory is corrupt.
   at qpid.messaging.Message.getContentSize(Message* )
   at Org.Apache.Qpid.Messaging.Message.get_ContentSize() in 
      d:\qpid\cpp\bindings\qpid\dotnet\src\message.h:line 350
   at Org.Apache.Qpid.Messaging.Program.Main(String[] args) in 
      D:\qpid\cpp\...\csharp.example.helloworld.cs:line 80.
{noformat}

The code could be fixed up by adding a lock for thread safety and a check for disposed objects
that throws ObjectDisposed when seen.

{code:title=ProposedCode|borderStyle=solid}
System::String ^ Message::GetContent()
{
    System::String ^ result = nullptr;
    System::Exception ^ newException = nullptr;

    msclr::lock lk(this);

    if (NULL == messagep)
    {
        newException = gcnew 
            ObjectDisposedException("Message");
    }
    else
    {
        try 
        {
            result = gcnew String(messagep->getContent().c_str());
        } 
        catch (const ::qpid::types::Exception & error) 
        {
            String ^ errmsg = gcnew String(error.what());
            newException    = gcnew QpidException(errmsg);
        }
    }

    if (newException != nullptr) 
    {
        throw newException;
    }

    return result;
}
{code}

This same pattern must be applied to all function and property references to all Messaging
bound classes.

> .NET Binding for Messaging classes need a test to check that binding is still in effect
> ---------------------------------------------------------------------------------------
>
>                 Key: QPID-3193
>                 URL: https://issues.apache.org/jira/browse/QPID-3193
>             Project: Qpid
>          Issue Type: Improvement
>    Affects Versions: 0.11
>            Reporter: Chuck Rolke
>            Assignee: Chuck Rolke
>
> The .NET Binding for Messaging could be made more user-friendly with the addition of
a property that indicates whether or not the underlying binding is still available. A C# coder
may innocently write:
> (1)  Message mA = new Message("a");
> (2)  Message mB = mA;
>      ...
> (N)  mB.Dispose();
> After disposing of message mB then message mA is clobbered. 'Message' is a 'ref class'
type and messages mA and mB refer to the same object on managed heap. When message mB is disposed
then the bound C++ Messaging object is deleted [1]. Any reference to the bound message part
of mA will result in an illegal memory reference (to 0) and a process exit. The .NET runtime
can't catch this fault.
> The obvious answer is not to do that. If the second line of code was 'Message mB = new
Message(mA)' then mA and mB would have been completely separate and disposing of either would
have no effect on the other.
> Another answer is to have the binding check for a null binding reference on each and
every access and then to throw if the underlying binding is gone. This is not very appealing
from a performance standpoint.
> As a compromise I would like to add a property isBound to each class. Users then have
a fighting chance to check that the binding is still in effect and that function calls on
the object shouldn't blow up. This property would be useful in Assert statements or in debugging.
> [1] If anyone knows how to have my binding library intercept example code line (2) and
create reference counts, please let me know.

--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira

---------------------------------------------------------------------
Apache Qpid - AMQP Messaging Implementation
Project:      http://qpid.apache.org
Use/Interact: mailto:dev-subscribe@qpid.apache.org


Mime
View raw message