Forking

The rest of the initialization process depends on value of dont_fork variable. dont_fork is a global variable defined in main.c. We will describe both variants separatelly.

dont_fork variable is set (not zero)

If dont_fork variable is set, the server will be operating in special mode. There will be only one process processing incoming requests. This is very slow and was intended mainly for debugging purposes. The main process will be proccessing all incoming requests itself.

The server still needs additional children:

The following initialization will be performed in dont fork mode. (look into function main_loop in file main.c.

That's it. Everything has been initialized properly and as the last step we will call udp_rcv_loop which is the main loop function. The function will be described later.

dont_fork is not set (zero)

dont_fork is not set. That means that the server will fork children and the children will be processing incoming requests. How many childrens will be created depends on the configuration (children variable). The main process will be sleeping and handling signals only.

The main process will then initialize the FIFO server. The FIFO server needs another child to handle communication over FIFO and thus another child will be created. The FIFO server will be described in more detail later.

Then the main process will perform another fork for the timer attendand. The child will take care of timer lists and execute specified function when a timer hits.

The main process is now completely initialized, it will sleep in pause function untill a signal comes and call handle_sigs when such condition occurs.

The following initialization will be performed by each child separately:

Each child executes init_child function. The function will sequentially call child_init functions of all loaded modules.

Becuase the function is called in each child separately, it can initialize per-child specific data. For example if a module needs to communicate with database, it must open a database connection. If the connection would be opened in mod_init function, all the children would share the same connection and locking would be neccessary to avoid conflicts. On the other hand if the connection was opened in child_init function, each child will have its own connection and concurrency conflicts will be handled by the database server.

And last, but not least, each child executes udp_rcv_loop function which contains the main loop logic.