Просмотр исходного кода

Experiments with sendfile for Linux

bel2125 10 лет назад
Родитель
Сommit
c762a77c0e
1 измененных файлов с 37 добавлено и 20 удалено
  1. 37 20
      src/civetweb.c

+ 37 - 20
src/civetweb.c

@@ -5238,37 +5238,54 @@ static void send_file_data(struct mg_connection *conn,
 	offset = offset < 0 ? 0 : offset > size ? size : offset;
 
 	if (len > 0 && filep->membuf != NULL && size > 0) {
+		/* file stored in memory */
 		if (len > size - offset) {
 			len = size - offset;
 		}
 		mg_write(conn, filep->membuf + offset, (size_t)len);
 	} else if (len > 0 && filep->fp != NULL) {
+		/* file stored on disk */
+#if defined(LINUX_SENDFILE_TEST)
+/* TODO: Test sendfile for Linux */
+                if (conn->throttle==0 && conn->ssl==0) {
+			off_t offs = (off_t)offset;
+			ssize_t sent = sendfile(conn->client.sock, fileno(filep->fp), &offs, (size_t)len);
+                        if (sent>0) {
+				conn->num_bytes_sent += sent;
+				return;
+                        }
+			/* sent<0 means error --> try classic way */          
+			mg_cry(conn, "%s: sendfile() failed: %s (trying read/write)", __func__, strerror(ERRNO));
+		}
+#else
 		if (offset > 0 && fseeko(filep->fp, offset, SEEK_SET) != 0) {
 			mg_cry(conn, "%s: fseeko() failed: %s", __func__, strerror(ERRNO));
-		}
-		while (len > 0) {
-			/* Calculate how much to read from the file in the buffer */
-			to_read = sizeof(buf);
-			if ((int64_t)to_read > len) {
-				to_read = (int)len;
-			}
+		} else {
+			while (len > 0) {
+				/* Calculate how much to read from the file in the buffer */
+				to_read = sizeof(buf);
+				if ((int64_t)to_read > len) {
+					to_read = (int)len;
+				}
 
-			/* Read from file, exit the loop on error */
-			if ((num_read = (int)fread(buf, 1, (size_t)to_read, filep->fp)) <=
-			    0) {
-				break;
-			}
+				/* Read from file, exit the loop on error */
+				if ((num_read = (int)fread(buf, 1, (size_t)to_read, filep->fp)) <=
+				    0) {
+					break;
+				}
 
-			/* Send read bytes to the client, exit the loop on error */
-			if ((num_written = mg_write(conn, buf, (size_t)num_read)) !=
-			    num_read) {
-				break;
-			}
+				/* Send read bytes to the client, exit the loop on error */
+				if ((num_written = mg_write(conn, buf, (size_t)num_read)) !=
+				    num_read) {
+					break;
+				}
 
-			/* Both read and were successful, adjust counters */
-			conn->num_bytes_sent += num_written;
-			len -= num_written;
+				/* Both read and were successful, adjust counters */
+				conn->num_bytes_sent += num_written;
+				len -= num_written;
+			}
 		}
+#endif
 	}
 }