Simonr
unread,Aug 18, 2010, 7:18:44 AM8/18/10Sign in to reply to author
Sign in to forward
You do not have permission to delete messages in this group
Either email addresses are anonymous for this group or you need the view member email addresses permission to view the original message
to C++ RTMP Server
Hi,
If anybodies interested... I have implemented MMAP for the windows
code:
Add the following to Win32platform.h:
#define MAP_NOCACHE (0)
#define MAP_NOEXTEND 0x0100 /* for MAP_FILE, don't change file size
*/
#define MAP_FAILED ((void *) -1)
#define O_RDONLY 0x0000
#define O_RDWR 0x0002
#define PROT_READ 0x1 /* Page can be read. */
#define PROT_WRITE 0x2 /* Page can be written. */
#define PROT_EXEC 0x4 /* Page can be executed. */
#define PROT_NONE 0x0 /* Page can not be accessed.
*/
#define MAP_SHARED 0x01 /* Share changes. */
#define MAP_PRIVATE 0x02 /* Changes are private. */
#define MAP_FIXED 0x10 /* Interpret addr exactly.
*/
DLLEXP long getpagesize (void);
DLLEXP long getregionsize (void);
DLLEXP void *mmap(void *start, size_t len, int prot, int flags, int
fd, off_t offset);
DLLEXP int munmap(void *start, size_t len);
Add the following to Win32platform.cpp
long getpagesize (void) {
static long g_pagesize = 0;
if (! g_pagesize) {
SYSTEM_INFO system_info;
GetSystemInfo (&system_info);
g_pagesize = system_info.dwPageSize;
}
return g_pagesize;
}
long getregionsize (void) {
static long g_regionsize = 0;
if (! g_regionsize) {
SYSTEM_INFO system_info;
GetSystemInfo (&system_info);
g_regionsize = system_info.dwAllocationGranularity;
}
return g_regionsize;
}
void *mmap(void *start, size_t len, int prot, int flags, int fd, off_t
offset) {
/*
This is a minimal implementation supporting:
PROT_NONE, PROT_READ, PROT_WRITE, PROT_EXEC
It handles the following mapping flags:
MAP_NOCACHE, MAP_FIXED, MAP_SHARED, MAP_PRIVATE
*/
void *ret = MAP_FAILED;
HANDLE hmap = NULL;
long wprot = 0, wflags = 0;
HANDLE hfile = (HANDLE)_get_osfhandle(fd);
long file_len = _filelength(fd);
/* map *NIX protections and flags to their WIN32 equivalents */
if ((prot & PROT_READ) && (~prot & PROT_WRITE)) {
/* read only, maybe exec */
wprot = (prot & PROT_EXEC) ? (PAGE_EXECUTE_READ) :
(PAGE_READONLY);
wflags = (prot & PROT_EXEC) ? (FILE_MAP_EXECUTE) :
(FILE_MAP_READ);
if (flags & MAP_NOCACHE)
wprot = wprot| SEC_NOCACHE;
}
else if (prot & PROT_WRITE) {
/* read/write, maybe exec */
if ((flags & MAP_SHARED) && (~flags & MAP_PRIVATE)) {
/* changes are committed to the file */
wprot = (prot & PROT_EXEC) ? (PAGE_EXECUTE_READWRITE) :
(PAGE_READWRITE);
wflags = (prot & PROT_EXEC) ? (FILE_MAP_EXECUTE) :
(FILE_MAP_WRITE);
}
else if ((flags & MAP_PRIVATE) && (~flags & MAP_SHARED)) {
/* does not affect the original file */
wprot = PAGE_WRITECOPY;
wflags = FILE_MAP_COPY;
}
else {
/* MAP_PRIVATE + MAP_SHARED is not allowed, abort */
errno = EINVAL;
return MAP_FAILED;
}
}
int granularityOffset = (int)(offset % getregionsize());
offset -= granularityOffset; // align offset
len = (offset+len+granularityOffset > file_len) ? file_len-offset-
granularityOffset : len; //check to see if offset + len in bounds
/* create the windows map object */
hmap = CreateFileMapping(hfile, NULL, wprot, 0, offset+len
+granularityOffset, NULL);
if (hmap == NULL) {
/* the fd was checked before, so it must have bad access rights */
errno = EPERM;
return MAP_FAILED;
}
ret = MapViewOfFileEx(hmap, wflags, 0, offset, len +
granularityOffset,
(flags & MAP_FIXED) ? (start) : (NULL));
int err = GetLastError();
/* Drop the map, it will not be deleted until last 'view' is
closed */
CloseHandle(hmap);
if (ret == NULL || err!=0) {
/* if MAP_FIXED was set, the address was probably wrong */
errno = (flags & MAP_FIXED) ? (EINVAL) : (ENOMEM);
return MAP_FAILED;
}
if (granularityOffset) //map the return base address to viewoffile
base address
_mmap_map[(void *) ((char *)ret + granularityOffset)] = ret;
return ((void *) ((char *)ret + granularityOffset));
}
int munmap(void *start, size_t len)
{
if (start == NULL) {
errno = EINVAL;
return -1;
}
if (MAP_HAS1(_mmap_map, start)) // does it have a adjusted base for
granularity?
return UnmapViewOfFile(_mmap_map[start]) ? 0 : -1;
else
return UnmapViewOfFile(start) ? 0 : -1;
}
change: class MmapPointer to: class DLLEXP MmapPointer
change: class DLLEXP MmapFile to: class DLLEXP MmapFile
Then just define HAS_MMAP for the thelib and common projects.
Regards,
Simon