[ccan] RFC: draft rfc822 module

David Gibson david at gibson.dropbear.id.au
Tue May 22 23:37:32 EST 2012


On Tue, May 22, 2012 at 01:35:14PM +0930, Paul 'Rusty' Russell wrote:
> On Mon, 21 May 2012 05:59:31 -0500, Jonathan Nieder <jrnieder at gmail.com> wrote:
> > David Gibson wrote:
> > > On Sun, May 20, 2012 at 09:38:09PM -0500, Jonathan Nieder wrote:
> > >> David Gibson wrote:
> > 
> > >>> --- /dev/null
> > >>> +++ b/ccan/rfc822/test/run-allocation-failure.c
> > >>> @@ -0,0 +1,56 @@
> > >> [...]
> > >>> +	talloc_set_allocator(failing_malloc, free, realloc);
> > >>
> > >> By the way, as an alternative to the rfc822 allocation failure
> > >> callback, I can set up exit-cleanly-on-failed-allocation semantics
> > >> here.  I can even use talloc_add_external to make my handler's
> > >> behavior depend on the talloc context.
> > >
> > > Um.. I'm not sure what you mean by this.
> > 
> > Sorry, thinko on my part.
> > 
> > What I meant is that a caller who wants to exit(1) instead of abort()
> > for allocation failures can make talloc take care of that, using
> > talloc_set_allocator() or talloc_add_external().
> > 
> > The thinko was that if the caller wants to suppress the abort() but
> > does not want to exit, this trick isn't enough.  It can't replace the
> > functionality of the rfc822 failed allocation handler completely.
> > 
> > Drat, error handling is _hard_.
> 
> Yes, and experience shows that no one handles OOM correctly, so spending
> effort on it is dubious.
> 
> One thought:
> 
> It's tempting to expose 'struct rfc822' in the header, and let the
> caller allocate and free it (ie. provide rfc822_init() and
> rfc822_cleanup()).  I'm moving to this pattern, because a fair few CCAN
> users are interested int tiny systems (and thus resent malloc usage).
> 
> Less of an advantage for you, since you allocate internally.  But you
> could then provide a global hook for alloc/resize/free which hands the
> msg.  Talloc users can easily make this a wrapper (or that could be the
> default).  If you end up using complex allocations internally, then you
> might want to insist that it be talloc.

Uh, I already do, since it will be doing complex allocations
internally.  It already allocates a list of headers, and there will be
more once we have indexing of headers, unfolding and other such
things.

> Error handling could be done here:
> 
>         static void *myalloc(struct rfc822 *msg, size_t len)
>         {
>                 void *ret = talloc(msg, len);
>                 if (!ret) {
>                         struct myrfc822 *mymsg = (struct myrfc822 *)msg;
>                         mymsg->alloc_failed++;
>                 }
>                 return ret;
>         }

I don't quite see what that does differently from what I already
have.  It already requires talloc, and internal data structures are
allocated using the message structure as a context.

-- 
David Gibson			| I'll have my music baroque, and my code
david AT gibson.dropbear.id.au	| minimalist, thank you.  NOT _the_ _other_
				| _way_ _around_!
http://www.ozlabs.org/~dgibson


More information about the ccan mailing list