Libabc: Best practices for library writers from Lennart Poettering
0pointer.de
0pointer.de
Lennart Poetering is the author of PulseAudio. He probably has a bone or two to pick with ALSA.
[1] http://bazaar.launchpad.net/~ubuntu-branches/ubuntu/precise/...
static int get_string_hash(const char *s)
{
int val = 0;
if (s == NULL)
return val;
while (*s)
val += *s++;
return val & ALISP_OBJ_PAIR_HASH_MASK;
}
It seems to cleverly avoid everything that's supposed to go into a string hash function, and makes me quite wary of the rest of the file's code quality. I stopped reading after checking that this function is indeed used (it is).Also, the file itself was last modified on 2011-10-18, which seems to be pretty recent for something that's not used. Perhaps they're gearing up to start using it, and if that's going to involve any kind of even remotely performance-sensitive, I hope they replace the hash function first. :)
The biggest problem I see with this hash function is that it will produce very many collisions (because most common strings will probably produce only small numbers).
I have seen other very simple string hash functions which just take the 4 first bytes (or 4 last or some sort of other pattern) of the string and use them (interpreted as 32bit integer) as the hash.
> avoid locking and mutexes, they are very unlikely to work correctly, and incredibly hard to get right.
For serious? Everything in this README is golden advice except for this. Locking can be reasoned about, it's not "incredibly hard", and it's often necessary.
In such an environment, it's much easier to accidentally create deadlocks that you know nothing about, because you can't predict the invocation pattern of all the libraries and applications potentially linking to you.
> zero global state -- Make your library threads-aware, but not thread-safe!
His point is that even if you have global state and try to protect that using locks, there may be code unknown to your application that works on the same global variables and you may not be able to predict the order of locking.
He specifically mentions the example of NSS (name service switch), which allows you to optionally create and plug in shared libraries that will be invoked without the application or the core C library being modified. So for example, an admin could change /etc/nsswitch.conf to set up LDAP user logins but your application could still use getpwnam(3) without caring about whether the pw retrieved is local, NIS, or LDAP.
From the README file endorsed by the OP:
--start quote--
use autotools
- every custom config/makefile build system is worse for everybody than autotools is
- we are all used to autotools, it works, nobody cares
- it's only two simple files to edit and include in git, which are well understood by many many people, not just you. . . .
- And really, anything but autotools is not an option. Just get over it. Everything else is crack, and it will come back to you if you choose anything else, sooner or later. Why? think cross compilation, installation/uninstallation, build root integration, separate object trees, standard adherence, tarball handling, make distcheck, portability between distros, ...