+ //
+ // We store our data in a file, so that we can send the data to the
+ // kernel only once (with write()). We then use sendfile() for each
+ // client, which effectively zero-copies it out of the kernel's buffer
+ // cache. This is significantly more efficient than doing write() from
+ // a userspace memory buffer, since the latter makes the kernel copy
+ // the same data from userspace many times.
+ int data_fd;
+
+ // How many bytes <data_fd> can hold (the buffer size).
+ size_t backlog_size;
+
+ // How many bytes this stream have received. Can very well be larger
+ // than <backlog_size>, since the buffer wraps.
+ size_t bytes_received;
+
+ // Clients that are in SENDING_DATA, but that we don't listen on,
+ // because we currently don't have any data for them.
+ // See put_client_to_sleep() and wake_up_all_clients().
+ std::vector<Client *> sleeping_clients;
+
+ // Clients that we recently got data for (when they were in
+ // <sleeping_clients>).
+ std::vector<Client *> to_process;
+
+ // What pool to fetch marks from, or NULL.
+ MarkPool *mark_pool;
+
+ // Put client to sleep, since there is no more data for it; we will on
+ // longer listen on POLLOUT until we get more data. Also, it will be put
+ // in the list of clients to wake up when we do.
+ void put_client_to_sleep(Client *client);