Add support for mmaps with nonzero offset values. Needs testing.

This commit is contained in:
Nick Mathewson 2010-10-25 12:10:10 -04:00
parent e72afae068
commit c2d9884a6a

View File

@ -2617,13 +2617,25 @@ evbuffer_file_segment_new(
#if defined(_EVENT_HAVE_MMAP) #if defined(_EVENT_HAVE_MMAP)
/* TODO: Implement an mmap-alike for windows. */ /* TODO: Implement an mmap-alike for windows. */
if (!(flags & EVBUF_FS_DISABLE_MMAP)) { if (!(flags & EVBUF_FS_DISABLE_MMAP)) {
/* some mmap implementations require offset to be a multiple of off_t offset_rounded = 0, offset_leftover = 0;
* the page size. most users of this api, are likely to use 0 void *mapped;
* so mapping everything is not likely to be a problem. if (offset) {
* TODO(niels): determine page size and round offset to that /* mmap implementations don't generally like us
* page size to avoid mapping too much memory. * to have an offset that isn't a round */
*/ #ifdef SC_PAGE_SIZE
void *mapped = mmap(NULL, length + offset, PROT_READ, long page_size = sysconf(SC_PAGE_SIZE);
#elif defined(_SC_PAGE_SIZE)
long page_size = sysconf(_SC_PAGE_SIZE);
#else
long page_size = 1;
#endif
if (page_size == -1)
goto err;
offset_leftover = offset % page_size;
offset_rounded = offset - offset_leftover;
}
mapped = mmap(NULL, length + offset_leftover,
PROT_READ,
#ifdef MAP_NOCACHE #ifdef MAP_NOCACHE
MAP_NOCACHE | /* ??? */ MAP_NOCACHE | /* ??? */
#endif #endif
@ -2631,14 +2643,14 @@ evbuffer_file_segment_new(
MAP_FILE | MAP_FILE |
#endif #endif
MAP_PRIVATE, MAP_PRIVATE,
fd, 0); fd, offset_rounded);
if (mapped == MAP_FAILED) { if (mapped == MAP_FAILED) {
event_warn("%s: mmap(%d, %d, %zu) failed", event_warn("%s: mmap(%d, %d, %zu) failed",
__func__, fd, 0, (size_t)(offset + length)); __func__, fd, 0, (size_t)(offset + length));
} else { } else {
seg->mapping = mapped; seg->mapping = mapped;
seg->contents = ((char*)mapped)+offset; seg->contents = (char*)mapped+offset_leftover;
seg->offset = offset; seg->offset = 0;
seg->type = EVBUF_FS_MMAP; seg->type = EVBUF_FS_MMAP;
goto done; goto done;
} }