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

ADT arm-eh ast-experimental enum forall-pointer-decay jacob/cs343-translation new-ast new-ast-unique-expr pthread-emulation qualifiedEnum
Last change on this file since fe68bdf was 0aec496, checked in by Thierry Delisle <tdelisle@…>, 5 years ago

First attempt at webserver, no option support yet

  • Property mode set to 100644
File size: 3.7 KB
Line 
1#include "worker.hfa"
2
3#define __USE_GNU
4
5#include <errno.h>
6#include <stdio.h>
7#include <string.h>
8extern "C" {
9 #include <sys/socket.h>
10 #include <sys/types.h>
11 #include <linux/fcntl.h>
12 #include <linux/stat.h>
13 #include <netinet/in.h>
14}
15
16#include <iofwd.hfa>
17
18#include "options.hfa"
19#include "protocol.hfa"
20#include "filecache.hfa"
21
22extern "C" {
23// extern ssize_t sendfile(int out_fd, int in_fd, off_t *offset, size_t count);
24extern ssize_t splice(int fd_in, loff_t *off_in, int fd_out, loff_t *off_out, size_t len, unsigned int flags);
25}
26
27ssize_t sendfile(int out_fd, int in_fd, off_t *offset, size_t count) {
28 return splice(in_fd, offset, out_fd, 0p, count, 0);
29}
30
31
32//=============================================================================================
33// Worker Thread
34//=============================================================================================
35void sendfile( Worker & this, int fd, int ans_fd, size_t count ) {
36 off_t offset = 0;
37 ssize_t ret;
38 SPLICE1: while(count > 0) {
39 ret = cfa_splice(ans_fd, &offset, this.pipe[1], 0p, count, 5);
40 if( ret < 0 ) {
41 if( errno != EAGAIN && errno != EWOULDBLOCK) continue SPLICE1;
42 abort( "splice [0] error: (%d) %s\n", (int)errno, strerror(errno) );
43 }
44
45 count -= ret;
46 offset += ret;
47 size_t in_pipe = ret;
48 SPLICE2: while(in_pipe > 0) {
49 ret = cfa_splice(this.pipe[0], 0p, fd, 0p, in_pipe, 5);
50 if( ret < 0 ) {
51 if( errno != EAGAIN && errno != EWOULDBLOCK) continue SPLICE2;
52 abort( "splice [1] error: (%d) %s\n", (int)errno, strerror(errno) );
53 }
54 in_pipe -= ret;
55 }
56
57 }
58}
59
60void ?{}( Worker & this ) {
61 ((thread&)this){ "Server Worker Thread", *options.the_cluster };
62 int ret = pipe(this.pipe);
63 if( ret < 0 ) { abort( "pipe error: (%d) %s\n", (int)errno, strerror(errno) ); }
64}
65
66void main( Worker & this ) {
67 CONNECTION:
68 while( int fd = take(wait_connect); fd >= 0) {
69 printf("New connection, waiting for requests\n");
70 REQUEST:
71 for() {
72 bool closed;
73 HttpCode code;
74 const char * file;
75 size_t name_size;
76
77 // Read the http request
78 size_t len = 1024;
79 char buffer[len];
80 printf("Reading request\n");
81 [code, closed, file, name_size] = http_read(fd, buffer, len);
82
83 // if we are done, break out of the loop
84 if( closed ) {
85 printf("Connection closed\n");
86 continue CONNECTION;
87 }
88
89 // If this wasn't a request retrun 400
90 if( code != OK200 ) {
91 printf("Invalid Request\n");
92 answer_error(fd, code);
93 continue REQUEST;
94 }
95
96 printf("Request for file %.*s\n", name_size, file);
97
98 // Get the fd from the file cache
99 int ans_fd;
100 size_t count;
101 [ans_fd, count] = get_file( file, name_size );
102
103 // If we can't find the file, return 404
104 if( ans_fd < 0 ) {
105 printf("File Not Found\n");
106 answer_error(fd, E404);
107 continue REQUEST;
108 }
109
110 // Send the header
111 answer_header(fd, count);
112
113 // Send the desired file
114 sendfile( this, fd, ans_fd, count);
115
116 printf("File sent\n");
117 }
118 }
119}
120
121//=============================================================================================
122// Acceptor Thread
123//=============================================================================================
124void ?{}( Acceptor & this, int sockfd, struct sockaddr * addr, socklen_t * addrlen, int flags ) {
125 ((thread&)this){ "Acceptor Thread", *options.the_cluster };
126 this.sockfd = sockfd;
127 this.addr = addr;
128 this.addrlen = addrlen;
129 this.flags = flags;
130}
131
132void main( Acceptor & this ) {
133 for() {
134 int ret = cfa_accept4( this.[sockfd, addr, addrlen, flags] );
135 if(ret < 0) {
136 if( errno == ECONNABORTED ) break;
137 abort( "accept error: (%d) %s\n", (int)errno, strerror(errno) );
138 }
139
140 printf("New connection accepted\n");
141 put( wait_connect, ret );
142 }
143}
Note: See TracBrowser for help on using the repository browser.