Fossil SCM

Improvements to "fossil server" performance on Windows.

drh 2017-12-28 20:37 trunk
Commit 47ade67e2b81419c71d3afb94062cae69d0cf72544ae9d3816183a3badd50db7
1 file changed +32 -26
+32 -26
--- src/winhttp.c
+++ src/winhttp.c
@@ -131,26 +131,26 @@
131131
/*
132132
** Process a single incoming HTTP request.
133133
*/
134134
static void win32_http_request(void *pAppData){
135135
HttpRequest *p = (HttpRequest*)pAppData;
136
- FILE *in = 0, *out = 0;
137
- int amt, got;
136
+ FILE *in = 0, *out = 0, *aux = 0;
137
+ int amt, got, i;
138138
int wanted = 0;
139139
char *z;
140140
char zCmdFName[MAX_PATH];
141141
char zRequestFName[MAX_PATH];
142142
char zReplyFName[MAX_PATH];
143143
char zCmd[2000]; /* Command-line to process the request */
144
- char zHdr[2000]; /* The HTTP request header */
144
+ char zHdr[4000]; /* The HTTP request header */
145145
146146
sqlite3_snprintf(MAX_PATH, zCmdFName,
147
- "%s_cmd%d.txt", zTempPrefix, p->id);
147
+ "%s_%06d_cmd.txt", zTempPrefix, p->id);
148148
sqlite3_snprintf(MAX_PATH, zRequestFName,
149
- "%s_in%d.txt", zTempPrefix, p->id);
149
+ "%s_%06d_in.txt", zTempPrefix, p->id);
150150
sqlite3_snprintf(MAX_PATH, zReplyFName,
151
- "%s_out%d.txt", zTempPrefix, p->id);
151
+ "%s_%06d_out.txt", zTempPrefix, p->id);
152152
amt = 0;
153153
while( amt<sizeof(zHdr) ){
154154
got = recv(p->s, &zHdr[amt], sizeof(zHdr)-1-amt, 0);
155155
if( got==SOCKET_ERROR ) goto end_request;
156156
if( got==0 ){
@@ -177,12 +177,11 @@
177177
}else{
178178
break;
179179
}
180180
wanted -= got;
181181
}
182
- fclose(out);
183
- out = 0;
182
+
184183
/*
185184
** The repository name is only needed if there was no open checkout. This
186185
** is designed to allow the open checkout for the interactive user to work
187186
** with the local Fossil server started via the "ui" command.
188187
*/
@@ -195,34 +194,38 @@
195194
}else{
196195
sqlite3_snprintf(sizeof(zCmd), zCmd, "%s%s\n%s\n%s",
197196
get_utf8_bom(0), zRequestFName, zReplyFName, inet_ntoa(p->addr.sin_addr)
198197
);
199198
}
200
- out = fossil_fopen(zCmdFName, "wb");
201
- if( out==0 ) goto end_request;
202
- fwrite(zCmd, 1, strlen(zCmd), out);
203
- fclose(out);
204
- out = 0;
199
+ aux = fossil_fopen(zCmdFName, "wb");
200
+ if( aux==0 ) goto end_request;
201
+ fwrite(zCmd, 1, strlen(zCmd), aux);
205202
206203
sqlite3_snprintf(sizeof(zCmd), zCmd, "\"%s\" http -args \"%s\" --nossl%s",
207204
g.nameOfExe, zCmdFName, p->zOptions
208205
);
206
+ in = fossil_fopen(zReplyFName, "w+b");
207
+ fflush(out);
208
+ fflush(aux);
209209
fossil_system(zCmd);
210
- in = fossil_fopen(zReplyFName, "rb");
211210
if( in ){
212211
while( (got = fread(zHdr, 1, sizeof(zHdr), in))>0 ){
213212
send(p->s, zHdr, got, 0);
214213
}
215214
}
216215
217216
end_request:
218217
if( out ) fclose(out);
218
+ if( aux ) fclose(aux);
219219
if( in ) fclose(in);
220220
closesocket(p->s);
221
- file_delete(zRequestFName);
222
- file_delete(zReplyFName);
223
- file_delete(zCmdFName);
221
+ /* Make multiple attempts to delete the temporary files. Sometimes AV
222
+ ** software keeps the files open for a few seconds, preventing the file
223
+ ** from being deleted on the first try. */
224
+ for(i=1; i<=10 && file_delete(zRequestFName); i++){ Sleep(1000*i); }
225
+ for(i=1; i<=10 && file_delete(zCmdFName); i++){ Sleep(1000*i); }
226
+ for(i=1; i<=10 && file_delete(zReplyFName); i++){ Sleep(1000*i); }
224227
fossil_free(p);
225228
}
226229
227230
/*
228231
** Process a single incoming SCGI request.
@@ -233,16 +236,16 @@
233236
int amt, got, nHdr, i;
234237
int wanted = 0;
235238
char zRequestFName[MAX_PATH];
236239
char zReplyFName[MAX_PATH];
237240
char zCmd[2000]; /* Command-line to process the request */
238
- char zHdr[2000]; /* The SCGI request header */
241
+ char zHdr[4000]; /* The SCGI request header */
239242
240243
sqlite3_snprintf(MAX_PATH, zRequestFName,
241
- "%s_in%d.txt", zTempPrefix, p->id);
244
+ "%s_%06d_in.txt", zTempPrefix, p->id);
242245
sqlite3_snprintf(MAX_PATH, zReplyFName,
243
- "%s_out%d.txt", zTempPrefix, p->id);
246
+ "%s_%06d_out.txt", zTempPrefix, p->id);
244247
out = fossil_fopen(zRequestFName, "wb");
245248
if( out==0 ) goto end_request;
246249
amt = 0;
247250
got = recv(p->s, zHdr, sizeof(zHdr), 0);
248251
if( got==SOCKET_ERROR ) goto end_request;
@@ -259,20 +262,19 @@
259262
got = recv(p->s, zHdr, wanted<sizeof(zHdr) ? wanted : sizeof(zHdr), 0);
260263
if( got<=0 ) break;
261264
fwrite(zHdr, 1, got, out);
262265
wanted += got;
263266
}
264
- fclose(out);
265
- out = 0;
266267
assert( g.zRepositoryName && g.zRepositoryName[0] );
267268
sqlite3_snprintf(sizeof(zCmd), zCmd,
268269
"\"%s\" http \"%s\" \"%s\" %s \"%s\" --scgi --nossl%s",
269270
g.nameOfExe, zRequestFName, zReplyFName, inet_ntoa(p->addr.sin_addr),
270271
g.zRepositoryName, p->zOptions
271272
);
273
+ in = fossil_fopen(zReplyFName, "w+b");
274
+ fflush(out);
272275
fossil_system(zCmd);
273
- in = fossil_fopen(zReplyFName, "rb");
274276
if( in ){
275277
while( (got = fread(zHdr, 1, sizeof(zHdr), in))>0 ){
276278
send(p->s, zHdr, got, 0);
277279
}
278280
}
@@ -279,12 +281,15 @@
279281
280282
end_request:
281283
if( out ) fclose(out);
282284
if( in ) fclose(in);
283285
closesocket(p->s);
284
- file_delete(zRequestFName);
285
- file_delete(zReplyFName);
286
+ /* Make multiple attempts to delete the temporary files. Sometimes AV
287
+ ** software keeps the files open for a few seconds, preventing the file
288
+ ** from being deleted on the first try. */
289
+ for(i=1; i<=10 && file_delete(zRequestFName); i++){ Sleep(1000*i); }
290
+ for(i=1; i<=10 && file_delete(zReplyFName); i++){ Sleep(1000*i); }
286291
fossil_free(p);
287292
}
288293
289294
290295
/*
@@ -387,12 +392,13 @@
387392
}
388393
}
389394
if( !GetTempPathW(MAX_PATH, zTmpPath) ){
390395
fossil_fatal("unable to get path to the temporary directory.");
391396
}
392
- zTempPrefix = mprintf("%sfossil_server_P%d_",
397
+ zTempPrefix = mprintf("%sfossil_server_P%d",
393398
fossil_unicode_to_utf8(zTmpPath), iPort);
399
+ fossil_print("Temporary files: %s*\n", zTempPrefix);
394400
fossil_print("Listening for %s requests on TCP port %d\n",
395401
(flags&HTTP_SERVER_SCGI)!=0?"SCGI":"HTTP", iPort);
396402
if( zBrowser ){
397403
zBrowser = mprintf(zBrowser /*works-like:"%d"*/, iPort);
398404
fossil_print("Launch webbrowser: %s\n", zBrowser);
399405
--- src/winhttp.c
+++ src/winhttp.c
@@ -131,26 +131,26 @@
131 /*
132 ** Process a single incoming HTTP request.
133 */
134 static void win32_http_request(void *pAppData){
135 HttpRequest *p = (HttpRequest*)pAppData;
136 FILE *in = 0, *out = 0;
137 int amt, got;
138 int wanted = 0;
139 char *z;
140 char zCmdFName[MAX_PATH];
141 char zRequestFName[MAX_PATH];
142 char zReplyFName[MAX_PATH];
143 char zCmd[2000]; /* Command-line to process the request */
144 char zHdr[2000]; /* The HTTP request header */
145
146 sqlite3_snprintf(MAX_PATH, zCmdFName,
147 "%s_cmd%d.txt", zTempPrefix, p->id);
148 sqlite3_snprintf(MAX_PATH, zRequestFName,
149 "%s_in%d.txt", zTempPrefix, p->id);
150 sqlite3_snprintf(MAX_PATH, zReplyFName,
151 "%s_out%d.txt", zTempPrefix, p->id);
152 amt = 0;
153 while( amt<sizeof(zHdr) ){
154 got = recv(p->s, &zHdr[amt], sizeof(zHdr)-1-amt, 0);
155 if( got==SOCKET_ERROR ) goto end_request;
156 if( got==0 ){
@@ -177,12 +177,11 @@
177 }else{
178 break;
179 }
180 wanted -= got;
181 }
182 fclose(out);
183 out = 0;
184 /*
185 ** The repository name is only needed if there was no open checkout. This
186 ** is designed to allow the open checkout for the interactive user to work
187 ** with the local Fossil server started via the "ui" command.
188 */
@@ -195,34 +194,38 @@
195 }else{
196 sqlite3_snprintf(sizeof(zCmd), zCmd, "%s%s\n%s\n%s",
197 get_utf8_bom(0), zRequestFName, zReplyFName, inet_ntoa(p->addr.sin_addr)
198 );
199 }
200 out = fossil_fopen(zCmdFName, "wb");
201 if( out==0 ) goto end_request;
202 fwrite(zCmd, 1, strlen(zCmd), out);
203 fclose(out);
204 out = 0;
205
206 sqlite3_snprintf(sizeof(zCmd), zCmd, "\"%s\" http -args \"%s\" --nossl%s",
207 g.nameOfExe, zCmdFName, p->zOptions
208 );
 
 
 
209 fossil_system(zCmd);
210 in = fossil_fopen(zReplyFName, "rb");
211 if( in ){
212 while( (got = fread(zHdr, 1, sizeof(zHdr), in))>0 ){
213 send(p->s, zHdr, got, 0);
214 }
215 }
216
217 end_request:
218 if( out ) fclose(out);
 
219 if( in ) fclose(in);
220 closesocket(p->s);
221 file_delete(zRequestFName);
222 file_delete(zReplyFName);
223 file_delete(zCmdFName);
 
 
 
224 fossil_free(p);
225 }
226
227 /*
228 ** Process a single incoming SCGI request.
@@ -233,16 +236,16 @@
233 int amt, got, nHdr, i;
234 int wanted = 0;
235 char zRequestFName[MAX_PATH];
236 char zReplyFName[MAX_PATH];
237 char zCmd[2000]; /* Command-line to process the request */
238 char zHdr[2000]; /* The SCGI request header */
239
240 sqlite3_snprintf(MAX_PATH, zRequestFName,
241 "%s_in%d.txt", zTempPrefix, p->id);
242 sqlite3_snprintf(MAX_PATH, zReplyFName,
243 "%s_out%d.txt", zTempPrefix, p->id);
244 out = fossil_fopen(zRequestFName, "wb");
245 if( out==0 ) goto end_request;
246 amt = 0;
247 got = recv(p->s, zHdr, sizeof(zHdr), 0);
248 if( got==SOCKET_ERROR ) goto end_request;
@@ -259,20 +262,19 @@
259 got = recv(p->s, zHdr, wanted<sizeof(zHdr) ? wanted : sizeof(zHdr), 0);
260 if( got<=0 ) break;
261 fwrite(zHdr, 1, got, out);
262 wanted += got;
263 }
264 fclose(out);
265 out = 0;
266 assert( g.zRepositoryName && g.zRepositoryName[0] );
267 sqlite3_snprintf(sizeof(zCmd), zCmd,
268 "\"%s\" http \"%s\" \"%s\" %s \"%s\" --scgi --nossl%s",
269 g.nameOfExe, zRequestFName, zReplyFName, inet_ntoa(p->addr.sin_addr),
270 g.zRepositoryName, p->zOptions
271 );
 
 
272 fossil_system(zCmd);
273 in = fossil_fopen(zReplyFName, "rb");
274 if( in ){
275 while( (got = fread(zHdr, 1, sizeof(zHdr), in))>0 ){
276 send(p->s, zHdr, got, 0);
277 }
278 }
@@ -279,12 +281,15 @@
279
280 end_request:
281 if( out ) fclose(out);
282 if( in ) fclose(in);
283 closesocket(p->s);
284 file_delete(zRequestFName);
285 file_delete(zReplyFName);
 
 
 
286 fossil_free(p);
287 }
288
289
290 /*
@@ -387,12 +392,13 @@
387 }
388 }
389 if( !GetTempPathW(MAX_PATH, zTmpPath) ){
390 fossil_fatal("unable to get path to the temporary directory.");
391 }
392 zTempPrefix = mprintf("%sfossil_server_P%d_",
393 fossil_unicode_to_utf8(zTmpPath), iPort);
 
394 fossil_print("Listening for %s requests on TCP port %d\n",
395 (flags&HTTP_SERVER_SCGI)!=0?"SCGI":"HTTP", iPort);
396 if( zBrowser ){
397 zBrowser = mprintf(zBrowser /*works-like:"%d"*/, iPort);
398 fossil_print("Launch webbrowser: %s\n", zBrowser);
399
--- src/winhttp.c
+++ src/winhttp.c
@@ -131,26 +131,26 @@
131 /*
132 ** Process a single incoming HTTP request.
133 */
134 static void win32_http_request(void *pAppData){
135 HttpRequest *p = (HttpRequest*)pAppData;
136 FILE *in = 0, *out = 0, *aux = 0;
137 int amt, got, i;
138 int wanted = 0;
139 char *z;
140 char zCmdFName[MAX_PATH];
141 char zRequestFName[MAX_PATH];
142 char zReplyFName[MAX_PATH];
143 char zCmd[2000]; /* Command-line to process the request */
144 char zHdr[4000]; /* The HTTP request header */
145
146 sqlite3_snprintf(MAX_PATH, zCmdFName,
147 "%s_%06d_cmd.txt", zTempPrefix, p->id);
148 sqlite3_snprintf(MAX_PATH, zRequestFName,
149 "%s_%06d_in.txt", zTempPrefix, p->id);
150 sqlite3_snprintf(MAX_PATH, zReplyFName,
151 "%s_%06d_out.txt", zTempPrefix, p->id);
152 amt = 0;
153 while( amt<sizeof(zHdr) ){
154 got = recv(p->s, &zHdr[amt], sizeof(zHdr)-1-amt, 0);
155 if( got==SOCKET_ERROR ) goto end_request;
156 if( got==0 ){
@@ -177,12 +177,11 @@
177 }else{
178 break;
179 }
180 wanted -= got;
181 }
182
 
183 /*
184 ** The repository name is only needed if there was no open checkout. This
185 ** is designed to allow the open checkout for the interactive user to work
186 ** with the local Fossil server started via the "ui" command.
187 */
@@ -195,34 +194,38 @@
194 }else{
195 sqlite3_snprintf(sizeof(zCmd), zCmd, "%s%s\n%s\n%s",
196 get_utf8_bom(0), zRequestFName, zReplyFName, inet_ntoa(p->addr.sin_addr)
197 );
198 }
199 aux = fossil_fopen(zCmdFName, "wb");
200 if( aux==0 ) goto end_request;
201 fwrite(zCmd, 1, strlen(zCmd), aux);
 
 
202
203 sqlite3_snprintf(sizeof(zCmd), zCmd, "\"%s\" http -args \"%s\" --nossl%s",
204 g.nameOfExe, zCmdFName, p->zOptions
205 );
206 in = fossil_fopen(zReplyFName, "w+b");
207 fflush(out);
208 fflush(aux);
209 fossil_system(zCmd);
 
210 if( in ){
211 while( (got = fread(zHdr, 1, sizeof(zHdr), in))>0 ){
212 send(p->s, zHdr, got, 0);
213 }
214 }
215
216 end_request:
217 if( out ) fclose(out);
218 if( aux ) fclose(aux);
219 if( in ) fclose(in);
220 closesocket(p->s);
221 /* Make multiple attempts to delete the temporary files. Sometimes AV
222 ** software keeps the files open for a few seconds, preventing the file
223 ** from being deleted on the first try. */
224 for(i=1; i<=10 && file_delete(zRequestFName); i++){ Sleep(1000*i); }
225 for(i=1; i<=10 && file_delete(zCmdFName); i++){ Sleep(1000*i); }
226 for(i=1; i<=10 && file_delete(zReplyFName); i++){ Sleep(1000*i); }
227 fossil_free(p);
228 }
229
230 /*
231 ** Process a single incoming SCGI request.
@@ -233,16 +236,16 @@
236 int amt, got, nHdr, i;
237 int wanted = 0;
238 char zRequestFName[MAX_PATH];
239 char zReplyFName[MAX_PATH];
240 char zCmd[2000]; /* Command-line to process the request */
241 char zHdr[4000]; /* The SCGI request header */
242
243 sqlite3_snprintf(MAX_PATH, zRequestFName,
244 "%s_%06d_in.txt", zTempPrefix, p->id);
245 sqlite3_snprintf(MAX_PATH, zReplyFName,
246 "%s_%06d_out.txt", zTempPrefix, p->id);
247 out = fossil_fopen(zRequestFName, "wb");
248 if( out==0 ) goto end_request;
249 amt = 0;
250 got = recv(p->s, zHdr, sizeof(zHdr), 0);
251 if( got==SOCKET_ERROR ) goto end_request;
@@ -259,20 +262,19 @@
262 got = recv(p->s, zHdr, wanted<sizeof(zHdr) ? wanted : sizeof(zHdr), 0);
263 if( got<=0 ) break;
264 fwrite(zHdr, 1, got, out);
265 wanted += got;
266 }
 
 
267 assert( g.zRepositoryName && g.zRepositoryName[0] );
268 sqlite3_snprintf(sizeof(zCmd), zCmd,
269 "\"%s\" http \"%s\" \"%s\" %s \"%s\" --scgi --nossl%s",
270 g.nameOfExe, zRequestFName, zReplyFName, inet_ntoa(p->addr.sin_addr),
271 g.zRepositoryName, p->zOptions
272 );
273 in = fossil_fopen(zReplyFName, "w+b");
274 fflush(out);
275 fossil_system(zCmd);
 
276 if( in ){
277 while( (got = fread(zHdr, 1, sizeof(zHdr), in))>0 ){
278 send(p->s, zHdr, got, 0);
279 }
280 }
@@ -279,12 +281,15 @@
281
282 end_request:
283 if( out ) fclose(out);
284 if( in ) fclose(in);
285 closesocket(p->s);
286 /* Make multiple attempts to delete the temporary files. Sometimes AV
287 ** software keeps the files open for a few seconds, preventing the file
288 ** from being deleted on the first try. */
289 for(i=1; i<=10 && file_delete(zRequestFName); i++){ Sleep(1000*i); }
290 for(i=1; i<=10 && file_delete(zReplyFName); i++){ Sleep(1000*i); }
291 fossil_free(p);
292 }
293
294
295 /*
@@ -387,12 +392,13 @@
392 }
393 }
394 if( !GetTempPathW(MAX_PATH, zTmpPath) ){
395 fossil_fatal("unable to get path to the temporary directory.");
396 }
397 zTempPrefix = mprintf("%sfossil_server_P%d",
398 fossil_unicode_to_utf8(zTmpPath), iPort);
399 fossil_print("Temporary files: %s*\n", zTempPrefix);
400 fossil_print("Listening for %s requests on TCP port %d\n",
401 (flags&HTTP_SERVER_SCGI)!=0?"SCGI":"HTTP", iPort);
402 if( zBrowser ){
403 zBrowser = mprintf(zBrowser /*works-like:"%d"*/, iPort);
404 fossil_print("Launch webbrowser: %s\n", zBrowser);
405

Keyboard Shortcuts

Open search /
Next entry (timeline) j
Previous entry (timeline) k
Open focused entry Enter
Show this help ?
Toggle theme Top nav button