Lighttpd Source Code Review - Intro
Lighttpd is a fast, efficient and popular web server. by it's efficiency, it is simple too. In contrast to other high efficient and event driven servers, it is simply single-threaded. Code base of lighttpd is built up by 123kloc, with all of it's modules included. In this post we want to explore the source code and understand the architecture.
At first, lets fetch the source code from it's repo
git clone https://git.lighttpd.net/lighttpd/lighttpd1.4.git lighttpd
Now, lets explore the directory hierarchy. Almost all of source files ar located at src directory. In
this directory there is 3 kinds of files:
- Basic utilties (
ck.h,first.h) - Core sources
- Modules' source files (any file with
mod_prefix)
Before we start explore, lets talk about some coding convention in lighttpd. In all condition evaluations the convention is that constant comes first. for example:
if(NULL != srv.errh) {...}
/* instead of */
if(srv.errh != NULL) {...}
This convention is called Yoda condition. There is no difference between two convention, it just makes
sense in comparing equality. With yoda condition, compiler will make an error if programmer accidentally
assign (using =) instead of comparision (using ==).
Next convention is to use function attributes extensively. Attributes are defined in first.h as macros
in order to make the source code more readable. Most used attributes are:
__attribute_noinline__for marking function to not be inlined at all.__attribute_returns_nonnull__function doesn't return NULL value. So compiler may ignore NULL-checking and optimize the code.__attribute_cold__marks the function as cold, means it is called rarelly.__attribute_hot__marks function as hot, means it is called frequently.
Setting function's hottness/coldness make compiler to place them toghether in a separate code section. This makes an opportunity in OS's swap to keep the hot section in memory and swap the cold section as it is not needed.
Definitions and macros defined in first.h is so important. Allmost all source files include it (as the
name says).
Checked functions
Now, let's look at ck.h (aka. check). This file defines basic functions that may return errors. Some
functions that are defined here is as:
ck_malloc,ck_calloc, ... for memory allocation as raw stdlib's but checks it's return value.- memory comparison and manipulations, like
ck_memcp*,ck_memzero,... - Backtracing functions, like
ck_btfor printing backtrace andck_bt_abortto print and abort. - Assertion utilities,
ck_assert,ck_assert_failed,ck_static_assert.
As this functions are checked, they are marked with corresponding attributes for compiler optimization,
for example ck_malloc is marked as __attribute_returns_nonnull__. In all situations if assertion
failes, ck_assert is called (it is a macro) that in turn calls ck_assert_failed and it prints
backtrace to stderr and aborts.