source: benchmark/io/http/worker.cfa@ 3c79ea9

ADT ast-experimental pthread-emulation qualifiedEnum
Last change on this file since 3c79ea9 was ef3c383, checked in by Thierry Delisle <tdelisle@…>, 4 years ago

Added statistics about sendfile in the webserver

  • 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 CONNECTION:
47 for() {
48 if( options.log ) sout | "=== Accepting connection ===";
49 int fd = cfa_accept4( this.[sockfd, addr, addrlen, flags], CFA_IO_LAZY );
50 if(fd < 0) {
51 if( errno == ECONNABORTED ) break;
52 if( this.done && (errno == EINVAL || errno == EBADF) ) break;
53 abort( "accept error: (%d) %s\n", (int)errno, strerror(errno) );
54 }
55 if(this.done) break;
56
57 if( options.log ) sout | "=== New connection" | fd | "" | ", waiting for requests ===";
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
66 size_t len = options.socket.buflen;
67 char buffer[len];
68 if( options.log ) sout | "=== Reading request ===";
69 [code, closed, file, name_size] = http_read(fd, buffer, len);
70
71 // if we are done, break out of the loop
72 if( closed ) break REQUEST;
73
74 // If this wasn't a request retrun 400
75 if( code != OK200 ) {
76 sout | "=== Invalid Request :" | code_val(code) | "===";
77 answer_error(fd, code);
78 continue REQUEST;
79 }
80
81 if(0 == strncmp(file, "plaintext", min(name_size, sizeof("plaintext") ))) {
82 if( options.log ) sout | "=== Request for /plaintext ===";
83
84 int ret = answer_plaintext(fd);
85 if( ret == -ECONNRESET ) break REQUEST;
86
87 if( options.log ) sout | "=== Answer sent ===";
88 continue REQUEST;
89 }
90
91 if(0 == strncmp(file, "ping", min(name_size, sizeof("ping") ))) {
92 if( options.log ) sout | "=== Request for /ping ===";
93
94 // Send the header
95 int ret = answer_empty(fd);
96 if( ret == -ECONNRESET ) break REQUEST;
97
98 if( options.log ) sout | "=== Answer sent ===";
99 continue REQUEST;
100 }
101
102 if( options.log ) {
103 sout | "=== Request for file " | nonl;
104 write(sout, file, name_size);
105 sout | " ===";
106 }
107
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
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 ) {
125 if( options.log ) {
126 sout | "=== File Not Found (" | nonl;
127 write(sout, file, name_size);
128 sout | ") ===";
129 }
130 answer_error(fd, E404);
131 continue REQUEST;
132 }
133
134 // Send the desired file
135 int ret = answer_sendfile( this.pipe, fd, ans_fd, count, this.stats.sendfile );
136 if( ret == -ECONNRESET ) break REQUEST;
137
138 if( options.log ) sout | "=== Answer sent ===";
139 }
140
141 if( options.log ) sout | "=== Connection closed ===";
142 continue CONNECTION;
143 }
144}
Note: See TracBrowser for help on using the repository browser.