This method, intended for request parsers, receives a stream of temporary
buffers until it determines that parsing is done, at which point it can
return any unconsumed partial buffer back to the input stream.
It is intended as a replacement for read_until(), since it can parse in a
single pass.
Runing on pre-glibc2.18 hosts (like C7) is impossible without this. The
downside is that the developer has to download, build, and install static
versions of libtcmalloc and libaio.
timer_set maintains next timeout so no need to duplicate it.
This also fixes a potential issue, if upon timer expiry no timer is
pending we did not update _next_timeout which will result in timer fd
not being updated upon next arm().
If you don't want to build eveything, you can narrow down the list of
artifacts liek this:
$ ./configure --with tests/test-reactor --with apps/httpd/httpd
It's less awkward to concatenate lists than strings. Having files in a
list is less prone to merge conflicts. It also makes the split() call
unnecessary.
By default both debug and release binaries are built. It makes the
build take longer than necessary, it's rarely needed to have both
versions during development. To build only one of them, do:
$ ./configure --mode debug
$ ninja
This patches shows what change is needed for http to run with multiple
event loops. This is not very useful still because actual work is not
yet distributed.
This patch adds an ability to specify how much threads seastart should
spawn. Each thread run its own instance of event loop. Separate
communication channel is created between each pair of threads.
Currently thread_pool implements cross-thread communication channel
internally. Separate communication logic into its own class to
reuse it for smp communication in later patches.
Simplify it for the many possible states of the unsent queue:
- empty: return an empty packet
- one small packet: dequeue and return
- one large packet at head: split and return
- many packets, starting with a small one: merge first, split last
Move reference counting into the deleter core, instead of relegating it
to a shared_deleter (which has to be allocated) and an external reference
counted (also allocated). This dramatically reduces dynamic allocations.
Instead of using internal_deleter, which is unwieldy, store the
header data inside packet::impl which we're allocating anyway.
This adds some complication when we need to reallocate impl (if
the number of fragments overflows), but usually saves two allocations:
one for the internal_deleter and one for the data itself.
deleter::share() is causing massive amounts of allocation. First,
since usually a packet's deleter is not a shared_deleter, we need to
allocate that shared_deleter. Second, we need an external reference
count which requires yet another allocation.
Making reference counting part of the deleter class would solve both of
these problems, but we cannot easily do that, since users hold
std::unique_ptr<deleter> which is clearly not sharable.
We could do a massive s/unique_ptr/shared_ptr/ here, but that would have
the side effect of making sharing "too easy" - you simply copy the pointer.
We'd like to keep it explicit.
So to make the change easier, rename the existing unique_ptr<deleter> as
plain "deleter", whereas the old "deleter" becomes deleter::impl:
old name new name
-------- --------
deleter deleter::impl
unique_ptr<deleter> deleter
with exactly the same semantics. A later patch can then add explicit sharing.