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

Don Radick dradick at mindspring.com
Sun Jan 16 21:20:27 CET 2005


Thanks for the thorough explanation!

All my previous MT work (not much really) was specifically concurrent or
performance programming.  It's a different mindset to think in terms of 
trading a bit of time for MY safety in an essentially single threaded
task.


On Sun, 2005-01-16 at 09:13 -0500, Glenn Puchtel wrote:
> 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
> 
> 
> _______________________________________________
> AGENTPP mailing list
> AGENTPP at agentpp.org
> http://agentpp.org/mailman/listinfo/agentpp




More information about the AGENTPP mailing list