[AGENT++] MT-safety of get_printable() -- yet another approach

Glenn Puchtel gpuchtel at gplicity.com
Sun Jan 16 15:13:49 CET 2005


Thread safety can be accomplished by using local (stack) variables and
returning an "object"; in this case a "std::string" object.

Now, before you cringe at this thought understand that goal is thread
safety (integrity) rather than performance.  However, the cost to
performance might not be as much as you think.  By returning an object
you afford the compiler the opportunity to implement what is known as
"Return Value Optimization", which eliminates the over head of one copy
constructor.

The following two methods should be thread safe (to the extent of
calling them and using the returned value):


const std::string OctetStr::get_printable() const
{
	std::string result;

	[code to copy current value into "result" goes here]

	return result;  // No, this is not returning a local variable
}


, or for copy... 



const std::string SafeGetPrintable(Oid oid) const
{
	std::string result = oid.get_printable();

	return result;  // No, this is not returning a local variable
}


Passing Oid by value (in SafeGetPrintable) you pay the cost of a
constructor but its now on the stack (which ensures its content will not
change for your thread). 

More than likely your compiler performs "Return Value Optimization"
(also known as RVO) so you avoid the cost of a constructor when
returning the std:string object.  Also, since you return a class object,
it gets destroyed when it goes out of scope so you avoid memory leaks as
an additional benefit to this approach.

All-in-all this approach is (arguably) a bit more expensive in regards
to performance, but since integrity is the goal and you are just going
to have to pay the cost (somewhere).

Regards,
Glenn



-----Original Message-----
From: agentpp-bounces at agentpp.org [mailto:agentpp-bounces at agentpp.org]
On Behalf Of maom_onet at poczta.onet.pl
Sent: Saturday, January 15, 2005 2:29 PM
To: Don Radick
Cc: agentpp at agentpp.org
Subject: Re: Re: Re: [AGENT++] MT-safety of get_printable() (was:
SNMP++advocacy)

Użytkownik Don Radick <dradick at mindspring.com> napisał:
>On Fri, 2005-01-14 at 10:42 +0100, maom_onet at poczta.onet.pl wrote:
>> Użytkownik Don Radick <dradick at mindspring.com> napisał:
>> >On Wed, 2005-01-12 at 23:35 +0100, maom_onet at poczta.onet.pl wrote:
>> >> A possible approach would be:
>> >> 
>> >> if (addr_changed)
>> >> {
>> >>    char buf[LARGE_ENOUGH];
>> >>    format_output(buf);
>> >>    strcpy(output_buffer, buf);
>> >>    addr_changed = false;
>> >> }
>> >> return output_buffer;
>> >> 
>> >> There is some overhead but this guarantees "strong MT-safety".
>You are correct.  I was continuing to think in MT terms. and your
>solution will simply require the other thread to wait on the buffer
>copy.

Another MT-safe approach uses a temporary copy of an object, e.g.:

bool SafeGetPrintable(const Oid& oid, std::string& s) {

    Oid oidCopy(oid);
    if (!oidCopy.valid())
        return false;
    const char* ptr = oidCopy.get_printable();
    if (!ptr)
        return false;
    s = ptr;
    return s == ptr;    // be paranoid
}

Looks a bit paranoid, especially error checks, but the idea is to use a
copy. Theoretically looks like a big overhead, and this is true to some
degree; however, get_printable() in Oid class allocates dynamically a
buffer (OctetStr seems to do the same), so when we use a temporary
object, this buffer is not created nor held for our object.

But in fact, I think a final solution would be to provide
get_printable(buf, buflen) functions.

Marek
_______________________________________________
AGENTPP mailing list
AGENTPP at agentpp.org
http://agentpp.org/mailman/listinfo/agentpp





More information about the AGENTPP mailing list