]> git.sesse.net Git - cubemap/blob - stream.h
efedc9b404a7f3c71e90fbb4fdb412e7ac58f5e5
[cubemap] / stream.h
1 #ifndef _STREAM_H
2 #define _STREAM_H 1
3
4 // Representation of a single, muxed (we only really care about bytes/blocks) stream.
5 // Fed by Input, sent out by Server (to Client).
6
7 #include <stdint.h>
8 #include <string>
9 #include <vector>
10
11 struct Client;
12 class MarkPool;
13 class StreamProto;
14
15 struct Stream {
16         Stream(const std::string &stream_id, size_t backlog_size);
17         ~Stream();
18
19         // Serialization/deserialization.
20         Stream(const StreamProto &serialized);
21         StreamProto serialize();
22
23         std::string stream_id;
24
25         // The HTTP response header, plus the video stream header (if any).
26         std::string header;
27
28         // The stream data itself, stored in a circular buffer.
29         //
30         // We store our data in a file, so that we can send the data to the
31         // kernel only once (with write()). We then use sendfile() for each
32         // client, which effectively zero-copies it out of the kernel's buffer
33         // cache. This is significantly more efficient than doing write() from
34         // a userspace memory buffer, since the latter makes the kernel copy
35         // the same data from userspace many times.
36         int data_fd;
37
38         // How many bytes <data_fd> can hold (the buffer size).
39         size_t backlog_size;
40
41         // How many bytes this stream have received. Can very well be larger
42         // than <backlog_size>, since the buffer wraps.
43         size_t bytes_received;
44         
45         // Clients that are in SENDING_DATA, but that we don't listen on,
46         // because we currently don't have any data for them.
47         // See put_client_to_sleep() and wake_up_all_clients().
48         std::vector<Client *> sleeping_clients;
49
50         // Clients that we recently got data for (when they were in
51         // <sleeping_clients>).
52         std::vector<Client *> to_process;
53
54         // What pool to fetch marks from, or NULL.
55         MarkPool *mark_pool;
56
57         // Put client to sleep, since there is no more data for it; we will on
58         // longer listen on POLLOUT until we get more data. Also, it will be put
59         // in the list of clients to wake up when we do.
60         void put_client_to_sleep(Client *client);
61
62         // We have more data, so mark all clients that are sleeping as ready to go.
63         void wake_up_all_clients();
64
65 private:
66         Stream(const Stream& other);
67 };
68
69 #endif  // !defined(_STREAM_H)