source: benchmark/io/http/worker.cfa @ b664af2

ADTarm-ehast-experimentalenumforall-pointer-decayjacob/cs343-translationnew-ast-unique-exprpthread-emulationqualifiedEnum
Last change on this file since b664af2 was 348f81d, checked in by Thierry Delisle <tdelisle@…>, 3 years ago

Added option to isolate processor so everything has it's own cluster

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