mirror of
https://github.com/cuberite/libevent.git
synced 2025-09-09 04:19:10 -04:00
Add CreateFileMapping file_segment implementation for win32
This commit is contained in:
parent
c2d9884a6a
commit
3f405d2d4b
57
buffer.c
57
buffer.c
@ -192,8 +192,13 @@ evbuffer_chain_free(struct evbuffer_chain *chain)
|
||||
EVBUFFER_CHAIN_EXTRA(
|
||||
struct evbuffer_chain_file_segment,
|
||||
chain);
|
||||
if (info->segment)
|
||||
if (info->segment) {
|
||||
#ifdef WIN32
|
||||
if (info->segment->type == EVBUF_FS_MMAP)
|
||||
UnmapViewOfFile(chain->buffer);
|
||||
#endif
|
||||
evbuffer_file_segment_free(info->segment);
|
||||
}
|
||||
}
|
||||
|
||||
mm_free(chain);
|
||||
@ -2615,7 +2620,6 @@ evbuffer_file_segment_new(
|
||||
}
|
||||
#endif
|
||||
#if defined(_EVENT_HAVE_MMAP)
|
||||
/* TODO: Implement an mmap-alike for windows. */
|
||||
if (!(flags & EVBUF_FS_DISABLE_MMAP)) {
|
||||
off_t offset_rounded = 0, offset_leftover = 0;
|
||||
void *mapped;
|
||||
@ -2656,6 +2660,24 @@ evbuffer_file_segment_new(
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#ifdef WIN32
|
||||
if (!(flags & EVBUF_FS_DISABLE_MMAP)) {
|
||||
long h = (long)_get_osfhandle(fd);
|
||||
HANDLE m;
|
||||
ev_uint64_t total_size = length+offset;
|
||||
if (h == (long)INVALID_HANDLE_VALUE)
|
||||
return NULL;
|
||||
m = CreateFileMapping((HANDLE)h, NULL, PAGE_READONLY,
|
||||
(total_size >> 32), total_size & 0xfffffffful,
|
||||
NULL);
|
||||
if (m != INVALID_HANDLE_VALUE) { /* Does h leak? */
|
||||
seg->mapping_handle = m;
|
||||
seg->offset = offset;
|
||||
seg->type = EVBUF_FS_MMAP;
|
||||
goto done;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
{
|
||||
ev_off_t start_pos = lseek(fd, 0, SEEK_CUR), pos;
|
||||
@ -2719,8 +2741,12 @@ evbuffer_file_segment_free(struct evbuffer_file_segment *seg)
|
||||
if (seg->type == EVBUF_FS_SENDFILE) {
|
||||
;
|
||||
} else if (seg->type == EVBUF_FS_MMAP) {
|
||||
#ifdef WIN32
|
||||
CloseHandle(seg->mapping_handle);
|
||||
#elif defined (_EVENT_HAVE_MMAP)
|
||||
if (munmap(seg->mapping, seg->length) == -1)
|
||||
event_warn("%s: munmap failed", __func__);
|
||||
#endif
|
||||
} else {
|
||||
EVUTIL_ASSERT(seg->type == EVBUF_FS_IO);
|
||||
mm_free(seg->contents);
|
||||
@ -2772,9 +2798,36 @@ evbuffer_add_file_segment(struct evbuffer *buf,
|
||||
chain->off = length;
|
||||
chain->buffer_len = chain->misalign + length;
|
||||
} else if (seg->type == EVBUF_FS_MMAP) {
|
||||
#ifdef WIN32
|
||||
ev_uint64_t total_offset = seg->offset+offset;
|
||||
ev_uint64_t offset_rounded=0, offset_remaining=0;
|
||||
LPVOID data;
|
||||
if (total_offset) {
|
||||
SYSTEM_INFO si;
|
||||
memset(&si, 0, sizeof(si)); /* cargo cult */
|
||||
GetSystemInfo(&si);
|
||||
offset_remaining = total_offset % si.dwAllocationGranularity;
|
||||
offset_rounded = total_offset - offset_remaining;
|
||||
}
|
||||
data = MapViewOfFile(
|
||||
seg->mapping_handle,
|
||||
FILE_MAP_READ,
|
||||
offset_rounded >> 32,
|
||||
offset_rounded & 0xfffffffful,
|
||||
length);
|
||||
if (data == NULL) {
|
||||
mm_free(chain);
|
||||
goto err;
|
||||
}
|
||||
chain->buffer = (unsigned char*) data;
|
||||
chain->buffer_len = length+offset_remaining;
|
||||
chain->misalign = offset_remaining;
|
||||
chain->off = length;
|
||||
#else
|
||||
chain->buffer = (unsigned char*)(seg->contents + offset);
|
||||
chain->buffer_len = length;
|
||||
chain->off = length;
|
||||
#endif
|
||||
} else {
|
||||
EVUTIL_ASSERT(seg->type == EVBUF_FS_IO);
|
||||
chain->buffer = (unsigned char*)(seg->contents + offset);
|
||||
|
@ -204,6 +204,10 @@ struct evbuffer_chain_reference {
|
||||
* evbuffer_chain with the EVBUFFER_FILESEGMENT flag set. */
|
||||
struct evbuffer_chain_file_segment {
|
||||
struct evbuffer_file_segment *segment;
|
||||
#ifdef WIN32
|
||||
/** If we're using CreateFileMapping, this is the handle to the view. */
|
||||
HANDLE view_handle;
|
||||
#endif
|
||||
};
|
||||
|
||||
/* Declared in event2/buffer.h; defined here. */
|
||||
@ -219,6 +223,10 @@ struct evbuffer_file_segment {
|
||||
int fd;
|
||||
/** If we're using mmap, this is the raw mapped memory. */
|
||||
void *mapping;
|
||||
#ifdef WIN32
|
||||
/** If we're using CreateFileMapping, this is the mapping */
|
||||
HANDLE mapping_handle;
|
||||
#endif
|
||||
/** If we're using mmap or IO, this is the content of the file
|
||||
* segment. */
|
||||
char *contents;
|
||||
@ -226,9 +234,9 @@ struct evbuffer_file_segment {
|
||||
* this data segment begins. If we're using sendfile, this is the
|
||||
* offset within the file where this data begins. If we're using IO,
|
||||
* this is 0. */
|
||||
off_t offset;
|
||||
ev_off_t offset;
|
||||
/** The length of this segment. */
|
||||
off_t length;
|
||||
ev_off_t length;
|
||||
};
|
||||
|
||||
#define EVBUFFER_CHAIN_SIZE sizeof(struct evbuffer_chain)
|
||||
|
Loading…
x
Reference in New Issue
Block a user