source: benchmark/io/http/worker.cfa @ 153570d

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

Added statistics about sendfile in the webserver

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