Product SiteDocumentation Site

4.2. Using libtcr for a pipelined server

After initializing the library with tc_run(3) a pool of pthreads is active to execute all subsequently created tc_threads. This pools of pthreads is destroyed when the starter function, which is an argument to tc_run(3), returns.
The starter function creates all necessary tc_threads, and sets up the listening socket(s). If a new connection comes in a new tc_thread_pool is created with the tc_thread_pool_new(3) function.

4.2.1. Input coordination

All threads of the tc_thread_pool simultaneously wait for an event on the client connection's FD with the tc_wait_fd(3) call. Only one of those tc_threads is woken up when the FD becomes ready. This tc_thread enters the READ stage. In case the available data is not a full request, the tc_thread in READ stage has to sleep again, to wait for the rest of that single request. At this point the tc_thread uses tc_wait_fd_prio(3) to wait for more data. When it has read in a full request, more data might already be available in the FD's input buffer. By calling tc_rearm(3), it wakes another tc_thread of the pool waiting in the first tc_wait_fd(3) call.


When there are multiple waiters in a tc_wait_fd(3) call waiting on the same event on one FD, only one is woken up when an event comes in. There is no control over which thread, specifically, wakes up.
If there are waiters in tc_wait_fd(3) and in a tc_wait_fd_prio(3) call, it is guaranteed that one of the waiters waiting in tc_wait_fd_prio(3) wakes up.
The calls to tc_wait_fd(3) and tc_rearm(3) create an atomic section, in regard to reading from the FD. Within that section only tc_wait_fd_prio(3) might be used to wait for more data.