source: benchmark/io/http/worker.cfa @ 86c12d65

ADTast-experimentalpthread-emulationqualifiedEnum
Last change on this file since 86c12d65 was 86c12d65, checked in by Thierry Delisle <tdelisle@…>, 2 years ago

Checkpoint of the broken version of reuseport

  • Property mode set to 100644
File size: 3.8 KB
Line 
1#include "worker.hfa"
2
3#include <errno.h>
4#include <stdio.h>
5#include <string.h>
6#include <unistd.h>
7
8#include <fstream.hfa>
9#include <iofwd.hfa>
10
11#include "options.hfa"
12#include "protocol.hfa"
13#include "filecache.hfa"
14
15//=============================================================================================
16// Worker Thread
17//=============================================================================================
18void ?{}( Worker & this ) {
19        size_t cli = rand() % options.clopts.cltr_cnt;
20        ((thread&)this){ "Server Worker Thread", *options.clopts.instance[cli], 64000 };
21        options.clopts.thrd_cnt[cli]++;
22        this.pipe[0] = -1;
23        this.pipe[1] = -1;
24        this.done = false;
25
26        this.stats.sendfile.calls = 0;
27        this.stats.sendfile.tries = 0;
28        this.stats.sendfile.header = 0;
29        this.stats.sendfile.splcin = 0;
30        this.stats.sendfile.splcot = 0;
31        for(i; zipf_cnts) {
32                this.stats.sendfile.avgrd[i].calls = 0;
33                this.stats.sendfile.avgrd[i].bytes = 0;
34        }
35}
36
37extern "C" {
38extern int accept4(int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags);
39}
40
41void main( Worker & this ) {
42        park();
43        /* paranoid */ assert( this.pipe[0] != -1 );
44        /* paranoid */ assert( this.pipe[1] != -1 );
45
46        const bool reuse = options.socket.manyreuse;
47
48        CONNECTION:
49        for() {
50                if( options.log ) sout | "=== Accepting connection ===";
51                int fd = cfa_accept4( this.[sockfd, addr, addrlen, flags], CFA_IO_LAZY );
52                if(fd < 0) {
53                        if( errno == ECONNABORTED ) break;
54                        if( this.done && (errno == EINVAL || errno == EBADF) ) break;
55                        abort( "accept error: (%d) %s\n", (int)errno, strerror(errno) );
56                }
57                if(this.done) break;
58
59                if( options.log ) sout | "=== New connection" | fd | "" | ", waiting for requests ===";
60                REQUEST:
61                for() {
62                        bool closed;
63                        HttpCode code;
64                        const char * file;
65                        size_t name_size;
66
67                        // Read the http request
68                        size_t len = options.socket.buflen;
69                        char buffer[len];
70                        if( options.log ) sout | "=== Reading request ===";
71                        [code, closed, file, name_size] = http_read(fd, buffer, len);
72
73                        // if we are done, break out of the loop
74                        if( closed ) break REQUEST;
75
76                        // If this wasn't a request retrun 400
77                        if( code != OK200 ) {
78                                sout | "=== Invalid Request :" | code_val(code) | "===";
79                                answer_error(fd, code);
80                                continue REQUEST;
81                        }
82
83                        if(0 == strncmp(file, "plaintext", min(name_size, sizeof("plaintext") ))) {
84                                if( options.log ) sout | "=== Request for /plaintext ===";
85
86                                int ret = answer_plaintext(fd);
87                                if( ret == -ECONNRESET ) break REQUEST;
88
89                                if( options.log ) sout | "=== Answer sent ===";
90                                continue REQUEST;
91                        }
92
93                        if(0 == strncmp(file, "ping", min(name_size, sizeof("ping") ))) {
94                                if( options.log ) sout | "=== Request for /ping ===";
95
96                                // Send the header
97                                int ret = answer_empty(fd);
98                                if( ret == -ECONNRESET ) break REQUEST;
99
100                                if( options.log ) sout | "=== Answer sent ===";
101                                continue REQUEST;
102                        }
103
104                        if( options.log ) {
105                                sout | "=== Request for file " | nonl;
106                                write(sout, file, name_size);
107                                sout | " ===";
108                        }
109
110                        if( !options.file_cache.path ) {
111                                if( options.log ) {
112                                        sout | "=== File Not Found (" | nonl;
113                                        write(sout, file, name_size);
114                                        sout | ") ===";
115                                }
116                                answer_error(fd, E405);
117                                continue REQUEST;
118                        }
119
120                        // Get the fd from the file cache
121                        int ans_fd;
122                        size_t count;
123                        [ans_fd, count] = get_file( file, name_size );
124
125                        // If we can't find the file, return 404
126                        if( ans_fd < 0 ) {
127                                if( options.log ) {
128                                        sout | "=== File Not Found (" | nonl;
129                                        write(sout, file, name_size);
130                                        sout | ") ===";
131                                }
132                                answer_error(fd, E404);
133                                continue REQUEST;
134                        }
135
136                        // Send the desired file
137                        int ret = answer_sendfile( this.pipe, fd, ans_fd, count, this.stats.sendfile );
138                        if( ret == -ECONNRESET ) break REQUEST;
139
140                        if( options.log ) sout | "=== Answer sent ===";
141                }
142
143                if( options.log ) sout | "=== Connection closed ===";
144                continue CONNECTION;
145        }
146}
Note: See TracBrowser for help on using the repository browser.