Browse code

Make both handle and memory based fmap API available always

The POSIX vs Win32 specific stuff is now only fmap_check_empty and a few helpers
only.

Török Edvin authored on 2011/06/15 03:26:59
Showing 2 changed files
... ...
@@ -50,6 +50,114 @@ static inline unsigned int fmap_which_page(fmap_t *m, size_t at);
50 50
 
51 51
 #ifndef _WIN32
52 52
 /* vvvvv POSIX STUFF BELOW vvvvv */
53
+static ssize_t pread_cb(void *handle, void *buf, size_t count, off_t offset);
54
+
55
+/* pread proto here in order to avoid the use of XOPEN and BSD_SOURCE
56
+   which may in turn prevent some mmap constants to be defined */
57
+ssize_t pread(int fd, void *buf, size_t count, off_t offset);
58
+
59
+fmap_t *fmap_check_empty(int fd, off_t offset, size_t len, int *empty) {
60
+    unsigned int pages, mapsz, hdrsz;
61
+    unsigned short dumb = 1;
62
+    int pgsz = cli_getpagesize();
63
+    struct stat st;
64
+    fmap_t *m;
65
+    void *handle = (void*)(ssize_t)fd;
66
+
67
+    *empty = 0;
68
+    if(fstat(fd, &st)) {
69
+	cli_warnmsg("fmap: fstat failed\n");
70
+	return NULL;
71
+    }
72
+
73
+    if(!len) len = st.st_size - offset; /* bound checked later */
74
+    if(!len) {
75
+	cli_dbgmsg("fmap: attempted void mapping\n");
76
+	*empty = 1;
77
+	return NULL;
78
+    }
79
+    if(!CLI_ISCONTAINED(0, st.st_size, offset, len)) {
80
+	cli_warnmsg("fmap: attempted oof mapping\n");
81
+	return NULL;
82
+    }
83
+    m = cl_fmap_open_handle((void*)(ssize_t)fd, offset, len, pread_cb, 1);
84
+    if (!m)
85
+	return NULL;
86
+    m->mtime = st.st_mtime;
87
+    m->handle_is_fd = 1;
88
+    return m;
89
+}
90
+#else
91
+/* vvvvv WIN32 STUFF BELOW vvvvv */
92
+static void unmap_win32(fmap_t *m) { /* WIN32 */
93
+    UnmapViewOfFile(m->data);
94
+    CloseHandle(m->mh);
95
+    free((void *)m);
96
+}
97
+
98
+fmap_t *fmap_check_empty(int fd, off_t offset, size_t len, int *empty) { /* WIN32 */
99
+    unsigned int pages, mapsz, hdrsz;
100
+    int pgsz = cli_getpagesize();
101
+    struct stat st;
102
+    fmap_t *m;
103
+    const void *data;
104
+    HANDLE fh;
105
+    HANDLE mh;
106
+
107
+    *empty = 0;
108
+    if(fstat(fd, &st)) {
109
+	cli_warnmsg("fmap: fstat failed\n");
110
+	return NULL;
111
+    }
112
+    if(offset < 0 || offset != fmap_align_to(offset, pgsz)) {
113
+	cli_warnmsg("fmap: attempted mapping with unaligned offset\n");
114
+	return NULL;
115
+    }
116
+    if(!len) len = st.st_size - offset; /* bound checked later */
117
+    if(!len) {
118
+	cli_dbgmsg("fmap: attempted void mapping\n");
119
+	*empty = 1;
120
+	return NULL;
121
+    }
122
+    if(!CLI_ISCONTAINED(0, st.st_size, offset, len)) {
123
+	cli_warnmsg("fmap: attempted oof mapping\n");
124
+	return NULL;
125
+    }
126
+
127
+    pages = fmap_align_items(len, pgsz);
128
+    hdrsz = fmap_align_to(sizeof(fmap_t), pgsz);
129
+
130
+    if((fh = (HANDLE)_get_osfhandle(fd)) == INVALID_HANDLE_VALUE) {
131
+	cli_errmsg("fmap: cannot get a valid handle for descriptor %d\n", fd);
132
+	return NULL;
133
+    }
134
+    if(!(mh = CreateFileMapping(m->fh, NULL, PAGE_READONLY, (DWORD)((len>>31)>>1), (DWORD)len, NULL))) {
135
+	cli_errmsg("fmap: cannot create a map of descriptor %d\n", fd);
136
+	CloseHandle(fh);
137
+	return NULL;
138
+    }
139
+    if(!(data = MapViewOfFile(m->mh, FILE_MAP_READ, (DWORD)((offset>>31)>>1), (DWORD)(offset), len))) {
140
+	cli_errmsg("fmap: cannot map file descriptor %d\n", fd);
141
+	CloseHandle(mh);
142
+	CloseHandle(fh);
143
+	return NULL;
144
+    }
145
+    if(!(m = cl_fmap_open_memory(data, len))) {
146
+	cli_errmsg("fmap: canot allocate fmap_t\n", fd);
147
+	CloseHandle(mh);
148
+	CloseHandle(fh);
149
+	return NULL;
150
+    }
151
+    m->handle = (void*)(ssize_t)fd;
152
+    m->handle_is_fd = 1;
153
+    m->fh = fh;
154
+    m->mh = mh;
155
+    m->unmap = unmap_win32;
156
+    return m;
157
+}
158
+#endif /* _WIN32 */
159
+
160
+/* vvvvv SHARED STUFF BELOW vvvvv */
53 161
 
54 162
 #define FM_MASK_COUNT 0x3fffffff
55 163
 #define FM_MASK_PAGED 0x40000000
... ...
@@ -88,48 +196,12 @@ pthread_mutex_t fmap_mutex = PTHREAD_MUTEX_INITIALIZER;
88 88
 
89 89
 #define fmap_bitmap (&m->placeholder_for_bitmap)
90 90
 
91
-/* pread proto here in order to avoid the use of XOPEN and BSD_SOURCE
92
-   which may in turn prevent some mmap constants to be defined */
93
-ssize_t pread(int fd, void *buf, size_t count, off_t offset);
94
-
95 91
 static const void *handle_need(fmap_t *m, size_t at, size_t len, int lock);
96 92
 static void handle_unneed_off(fmap_t *m, size_t at, size_t len);
97 93
 static const void *handle_need_offstr(fmap_t *m, size_t at, size_t len_hint);
98 94
 static const void *handle_gets(fmap_t *m, char *dst, size_t *at, size_t max_len);
99 95
 static void unmap_mmap(fmap_t *m);
100 96
 static void unmap_malloc(fmap_t *m);
101
-static ssize_t pread_cb(void *handle, void *buf, size_t count, off_t offset);
102
-
103
-fmap_t *fmap_check_empty(int fd, off_t offset, size_t len, int *empty) {
104
-    unsigned int pages, mapsz, hdrsz;
105
-    unsigned short dumb = 1;
106
-    int pgsz = cli_getpagesize();
107
-    struct stat st;
108
-    fmap_t *m;
109
-    void *handle = (void*)(ssize_t)fd;
110
-
111
-    *empty = 0;
112
-    if(fstat(fd, &st)) {
113
-	cli_warnmsg("fmap: fstat failed\n");
114
-	return NULL;
115
-    }
116
-
117
-    if(!len) len = st.st_size - offset; /* bound checked later */
118
-    if(!len) {
119
-	cli_dbgmsg("fmap: attempted void mapping\n");
120
-	*empty = 1;
121
-	return NULL;
122
-    }
123
-    if(!CLI_ISCONTAINED(0, st.st_size, offset, len)) {
124
-	cli_warnmsg("fmap: attempted oof mapping\n");
125
-	return NULL;
126
-    }
127
-    m = cl_fmap_open_handle((void*)(ssize_t)fd, offset, len, pread_cb, 1);
128
-    if (!m)
129
-	return NULL;
130
-    m->mtime = st.st_mtime;
131
-    return m;
132
-}
133 97
 
134 98
 extern cl_fmap_t *cl_fmap_open_handle(void *handle, size_t offset, size_t len,
135 99
 				      clcb_pread pread_cb, int use_aging)
... ...
@@ -280,7 +352,7 @@ static int fmap_readpage(fmap_t *m, unsigned int first_page, unsigned int count,
280 280
 
281 281
     fmap_lock;
282 282
     for(i=0; i<count; i++) { /* prefault */
283
-    	/* Not worth checking if the page is already paged, just ping each */
283
+	/* Not worth checking if the page is already paged, just ping each */
284 284
 	/* Also not worth reusing the loop below */
285 285
 	volatile char faultme;
286 286
 	faultme = ((char *)m)[(first_page+i) * m->pgsz + m->hdrsz];
... ...
@@ -324,7 +396,7 @@ static int fmap_readpage(fmap_t *m, unsigned int first_page, unsigned int count,
324 324
 
325 325
 	if(force_read) {
326 326
 	    /* we have some pending reads to perform */
327
-	    if (m->pread_cb == pread_cb) {
327
+	    if (m->handle_is_fd) {
328 328
 		unsigned int j;
329 329
 		int _fd = (int)(ssize_t)m->handle;
330 330
 		for(j=first_page; j<page; j++) {
... ...
@@ -559,14 +631,9 @@ static const void *handle_gets(fmap_t *m, char *dst, size_t *at, size_t max_len)
559 559
     return dst;
560 560
 }
561 561
 
562
-/* ^^^^^ POSIX STUFF AVOVE ^^^^^ */
562
+/* vvvvv MEMORY STUFF BELOW vvvvv */
563 563
 
564
-#else /* _WIN32 */
565
-
566
-/* vvvvv WIN32 STUFF BELOW vvvvv */
567
-
568
-static void unmap_win32(fmap_t *m);
569
-static const void *mem_need(fmap_t *m, size_t at, size_t len);
564
+static const void *mem_need(fmap_t *m, size_t at, size_t len, int lock);
570 565
 static void mem_unneed_off(fmap_t *m, size_t at, size_t len);
571 566
 static const void *mem_need_offstr(fmap_t *m, size_t at, size_t len_hint);
572 567
 static const void *mem_gets(fmap_t *m, char *dst, size_t *at, size_t max_len);
... ...
@@ -589,72 +656,8 @@ extern cl_fmap_t *cl_fmap_open_memory(const void *start, size_t len)
589 589
     m->unneed_off = mem_unneed_off;
590 590
 }
591 591
 
592
-fmap_t *fmap_check_empty(int fd, off_t offset, size_t len, int *empty) { /* WIN32 */
593
-    unsigned int pages, mapsz, hdrsz;
594
-    int pgsz = cli_getpagesize();
595
-    struct stat st;
596
-    fmap_t *m;
597
-    const void *data;
598
-    HANDLE fh;
599
-    HANDLE mh;
600 592
 
601
-    *empty = 0;
602
-    if(fstat(fd, &st)) {
603
-	cli_warnmsg("fmap: fstat failed\n");
604
-	return NULL;
605
-    }
606
-    if(offset < 0 || offset != fmap_align_to(offset, pgsz)) {
607
-	cli_warnmsg("fmap: attempted mapping with unaligned offset\n");
608
-	return NULL;
609
-    }
610
-    if(!len) len = st.st_size - offset; /* bound checked later */
611
-    if(!len) {
612
-	cli_dbgmsg("fmap: attempted void mapping\n");
613
-	*empty = 1;
614
-	return NULL;
615
-    }
616
-    if(!CLI_ISCONTAINED(0, st.st_size, offset, len)) {
617
-	cli_warnmsg("fmap: attempted oof mapping\n");
618
-	return NULL;
619
-    }
620
-
621
-    pages = fmap_align_items(len, pgsz);
622
-    hdrsz = fmap_align_to(sizeof(fmap_t), pgsz);
623
-
624
-    if((fh = (HANDLE)_get_osfhandle(fd)) == INVALID_HANDLE_VALUE) {
625
-	cli_errmsg("fmap: cannot get a valid handle for descriptor %d\n", fd);
626
-	return NULL;
627
-    }
628
-    if(!(mh = CreateFileMapping(m->fh, NULL, PAGE_READONLY, (DWORD)((len>>31)>>1), (DWORD)len, NULL))) {
629
-	cli_errmsg("fmap: cannot create a map of descriptor %d\n", fd);
630
-	CloseHandle(fh);
631
-	return NULL;
632
-    }
633
-    if(!(data = MapViewOfFile(m->mh, FILE_MAP_READ, (DWORD)((offset>>31)>>1), (DWORD)(offset), len))) {
634
-	cli_errmsg("fmap: cannot map file descriptor %d\n", fd);
635
-	CloseHandle(mh);
636
-	CloseHandle(fh);
637
-	return NULL;
638
-    }
639
-    if(!(m = cl_fmap_open_memory(data, len))) {
640
-	cli_errmsg("fmap: canot allocate fmap_t\n", fd);
641
-	CloseHandle(mh);
642
-	CloseHandle(fh);
643
-	return NULL;
644
-    }
645
-    m->fh = fh;
646
-    m->mh = mh;
647
-    m->unmap = unmap_win32;
648
-    return m;
649
-}
650
-
651
-static void unmap_win32(fmap_t *m) { /* WIN32 */
652
-    UnmapViewOfFile(m->data);
653
-    CloseHandle(m->mh);
654
-    free((void *)m);
655
-}
656
-
657
-static const void *mem_need(fmap_t *m, size_t at, size_t len) { /* WIN32 */
593
+static const void *mem_need(fmap_t *m, size_t at, size_t len, int lock) { /* WIN32 */
658 594
     if(!CLI_ISCONTAINED(0, m->len, at, len))
659 595
 	return NULL;
660 596
 
... ...
@@ -664,7 +667,6 @@ static const void *mem_need(fmap_t *m, size_t at, size_t len) { /* WIN32 */
664 664
 }
665 665
 
666 666
 static void mem_unneed_off(fmap_t *m, size_t at, size_t len) {}
667
-}
668 667
 
669 668
 static const void *mem_need_offstr(fmap_t *m, size_t at, size_t len_hint) {
670 669
     char *ptr = (char *)m->data + at;
... ...
@@ -700,11 +702,6 @@ static const void *mem_gets(fmap_t *m, char *dst, size_t *at, size_t max_len) {
700 700
     return dst;
701 701
 }
702 702
 
703
-#endif /* _WIN32 */
704
-
705
-
706
-/* vvvvv SHARED STUFF BELOW vvvvv */
707
-
708 703
 fmap_t *fmap(int fd, off_t offset, size_t len) {
709 704
     int unused;
710 705
     return fmap_check_empty(fd, offset, len, &unused);
... ...
@@ -725,7 +722,7 @@ static inline unsigned int fmap_which_page(fmap_t *m, size_t at) {
725 725
 int fmap_fd(fmap_t *m)
726 726
 {
727 727
     int fd;
728
-    if (m->pread_cb != pread_cb) {
728
+    if (!m->handle_is_fd) {
729 729
 	cli_warnmsg("fmap: trying to retrieve descriptor from something that is not\n");
730 730
 	return -1;
731 731
     }
... ...
@@ -46,9 +46,10 @@ struct cl_fmap {
46 46
     unsigned int paged;
47 47
     unsigned short aging;
48 48
     unsigned short dont_cache_flag;
49
+    unsigned short handle_is_fd;
49 50
 
50 51
     /* memory interface */
51
-    void *data;
52
+    const void *data;
52 53
 
53 54
     /* common interface */
54 55
     size_t offset;