libapi is a cross platform high performance io library written in C. It provides ability to write event driven servers and applications with continous code.
Writing event driven code in C is hard, and is harder to maintain.
There are libraries providing high level abstractions in this area, one of bests is a popular libuv. But decoupling application logic in various callbacks does not solve problem a lot.
By doing some research I come across combination of tasks also known as coroutines or fibers, and epoll/IOCP.
libapi was developed to solve this problem.
- cross platform (tested on ubuntu and on windows)
- high performance (benchmarks will be provided)
- no locks, no blocking
- easy to scale
- easy to develop
- timeout handling
- timers and idles
- bandwidth calculations
- error handling
- ipv4 and ipv6
- open source
- ssl stack with openssl
- http basic stack
- keep-alive with timeouts
- http pipelining
- https as ssl filter
for complete examples see demos
Main concepts are loop, stream and a task.
loop is an abstraction over epoll and IOCP, tht runs on a single thread. By starting a new loop new thread will be created. Each loop has its own pool to alloc/free memory.
stream is an abstraction over file, tcp, utp, pipe, tty and memory. Currently only file and tcp was implemented.
tasks are execution units with seperate stacks that they can be run in parallel within a single loop (single thread). In general scheduler will suspend a task that issued an io operation and will resume one for which an io operation was completed. This allows to keep stack variables alive during events in a loop, and as a result allows writing syncronous code. A task will be created as a result of calls api_loop_start, api_loop_post, api_loop_exec, api_loop_run
Creating a task requires also creating stack for it. Creating large stack is memory consuming, creating small stack will cause stack overflow. But what is bad that we dont know how much stack size will be needed for a particular task. By default will be created 8kb stack for a task. If task needs small stack this is not justified and memory consumed. In case when task needs more stack api_loop_call was designed.
The question is how grow up stack automatically on demand ?