comparison src/c/driver.c @ 167:2be573fec9a6

Unurlifying a datatype; longjmp-based error signaling mechanism
author Adam Chlipala <adamc@hcoop.net>
date Tue, 29 Jul 2008 15:25:42 -0400
parents b1b33f7cf555
children 71bafe66dbe1
comparison
equal deleted inserted replaced
166:a991431b77eb 167:2be573fec9a6
10 #include "lacweb.h" 10 #include "lacweb.h"
11 11
12 int lw_port = 8080; 12 int lw_port = 8080;
13 int lw_backlog = 10; 13 int lw_backlog = 10;
14 int lw_bufsize = 1024; 14 int lw_bufsize = 1024;
15
16 void lw_handle(lw_context, char*);
17 15
18 typedef struct node { 16 typedef struct node {
19 int fd; 17 int fd;
20 struct node *next; 18 struct node *next;
21 } *node; 19 } *node;
49 } 47 }
50 48
51 static pthread_mutex_t queue_mutex = PTHREAD_MUTEX_INITIALIZER; 49 static pthread_mutex_t queue_mutex = PTHREAD_MUTEX_INITIALIZER;
52 static pthread_cond_t queue_cond = PTHREAD_COND_INITIALIZER; 50 static pthread_cond_t queue_cond = PTHREAD_COND_INITIALIZER;
53 51
52 #define MAX_RETRIES 5
53
54 static void *worker(void *data) { 54 static void *worker(void *data) {
55 int me = *(int *)data; 55 int me = *(int *)data;
56 lw_context ctx = lw_init(1024, 1024); 56 lw_context ctx = lw_init(1024, 1024);
57 57
58 while (1) { 58 while (1) {
66 pthread_mutex_unlock(&queue_mutex); 66 pthread_mutex_unlock(&queue_mutex);
67 67
68 printf("Handling connection with thread #%d.\n", me); 68 printf("Handling connection with thread #%d.\n", me);
69 69
70 while (1) { 70 while (1) {
71 unsigned retries_left = MAX_RETRIES;
71 int r = recv(sock, back, lw_bufsize - (back - buf), 0); 72 int r = recv(sock, back, lw_bufsize - (back - buf), 0);
72 73
73 if (r < 0) { 74 if (r < 0) {
74 fprintf(stderr, "Recv failed\n"); 75 fprintf(stderr, "Recv failed\n");
75 break; 76 break;
136 } 137 }
137 } 138 }
138 139
139 printf("Serving URI %s....\n", path); 140 printf("Serving URI %s....\n", path);
140 141
141 lw_write (ctx, "HTTP/1.1 200 OK\r\n"); 142 while (1) {
142 lw_write(ctx, "Content-type: text/html\r\n\r\n"); 143 failure_kind fk;
143 lw_write(ctx, "<html>"); 144
144 lw_handle(ctx, path); 145 lw_write(ctx, "HTTP/1.1 200 OK\r\n");
145 lw_write(ctx, "</html>"); 146 lw_write(ctx, "Content-type: text/html\r\n\r\n");
147 lw_write(ctx, "<html>");
148
149 fk = lw_begin(ctx, path);
150 if (fk == SUCCESS) {
151 lw_write(ctx, "</html>");
152 break;
153 } else if (fk == BOUNDED_RETRY) {
154 if (retries_left) {
155 printf("Error triggers bounded retry: %s\n", lw_error_message(ctx));
156 --retries_left;
157 }
158 else {
159 printf("Fatal error (out of retries): %s\n", lw_error_message(ctx));
160
161 lw_reset_keep_error_message(ctx);
162 lw_write(ctx, "HTTP/1.1 500 Internal Server Error\n\r");
163 lw_write(ctx, "Content-type: text/plain\r\n\r\n");
164 lw_write(ctx, "Fatal error (out of retries): ");
165 lw_write(ctx, lw_error_message(ctx));
166 lw_write(ctx, "\n");
167 }
168 } else if (fk == UNLIMITED_RETRY)
169 printf("Error triggers unlimited retry: %s\n", lw_error_message(ctx));
170 else if (fk == FATAL) {
171 printf("Fatal error: %s\n", lw_error_message(ctx));
172
173 lw_reset_keep_error_message(ctx);
174 lw_write(ctx, "HTTP/1.1 500 Internal Server Error\n\r");
175 lw_write(ctx, "Content-type: text/plain\r\n\r\n");
176 lw_write(ctx, "Fatal error: ");
177 lw_write(ctx, lw_error_message(ctx));
178 lw_write(ctx, "\n");
179
180 break;
181 } else {
182 printf("Unknown lw_handle return code!\n");
183
184 lw_reset_keep_request(ctx);
185 lw_write(ctx, "HTTP/1.1 500 Internal Server Error\n\r");
186 lw_write(ctx, "Content-type: text/plain\r\n\r\n");
187 lw_write(ctx, "Unknown lw_handle return code!\n");
188
189 break;
190 }
191
192 lw_reset_keep_request(ctx);
193 }
146 194
147 lw_send(ctx, sock); 195 lw_send(ctx, sock);
148 196
149 printf("Done with client.\n\n"); 197 printf("Done with client.\n\n");
150 break; 198 break;