On Wed, 08.10.14 23:07, Zbigniew Jędrzejewski-Szmek (zbys...@in.waw.pl) wrote:

> > > > > A related thing: there's a mapping bus-error <-> errno implemented,
> > > > > but it only works for the errors defined in the library itself. It
> > > > > would be nice to extend this mapping to the "user" defined errors,
> > > > > e.g. in core/.  Would you be amenable to adding a mechianism to
> > > > > register additional mappings like bus-error-mapping.gperf so that they
> > > > > are used by the library?
> > > > 
> > > > Maybe have internal versions of the conversion calls that allow
> > > > passing in an additional table?
> > > That is not as convenient. E.g. sd_bus_error_set
> > > internally calls bus_error_name_to_errno. Currently, this always
> > > returns EIO for errors unknown to the library, and then the caller
> > > does it own lookup (e.g. looking at 
> > > transaction_add_job_and_dependencies()).
> > 
> > What precisely are you proposing instead?
> 
> typedef const name_error_mapping*
> (*bus_error_mapping_lookup_t) (const char *str, size_t len);
> 
> int bus_error_add_mapping(bus_error_mapping_lookup_t mapping);
> 
> This could be used to register a custom function similar to our
> bus_error_mapping_lookup(). It would get stored in a global table (of
> fixed size?), and bus_error_mapping_lookup would be the first slot in
> this table and the calls to bus_error_mapping_lookup would be
> replace by a function which iterates over this table and
> returns the first successful lookup.

I am really not a fan of global variables for things like this... If
it would be marked as TLS I'd feel a bit more comfortable though...

I wonder what it would take to make this work without any registration
code. i.e. we could use some executbale section tricks hidden in some
macros to allow any module to register mappings, and simply by being
compiled in we'd find them. 

In such a scheme the registration race and scope issues should go
away, since everything is always registered in all threads.

To define a map array, in as many .c files as desired:

__attribute((__section__("errnomap"))) __attribute((__used__)) const struct 
struct my_errno_map[] = { .... };

And then, use this to find the section:

    extern struct my_errno_map[] __start_errnomap;
    extern struct my_errno_map[] __stop_errnomap;

gcc supposedly maps this automatically to the start and end of the
section we defined above (yes, __start_ and __stop_ is magic), and
then we can just enumerate through them. And any .c module that
defines more maps transparently is found.

Or something like this?

Lennart

-- 
Lennart Poettering, Red Hat
_______________________________________________
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel

Reply via email to