Cache-FastMmap
view release on metacpan or search on metacpan
_mmc_set_error(cache, GetLastError(), "CloseHandle(fileMap) on shared file %s failed", cache->share_file);
UnmapViewOfFile(cache->mm_var);
CloseHandle(fileMap);
CloseHandle(cache->fh);
return -1;
}
return 0;
}
int mmc_check_fh(mmap_cache* cache) {
return 1;
}
int mmc_close_fh(mmap_cache* cache) {
int ret = CloseHandle(cache->fh);
cache->fh = NULL;
return ret;
}
int mmc_unmap_memory(mmap_cache* cache) {
int res = UnmapViewOfFile(cache->mm_var);
if (res == -1) {
_mmc_set_error(cache, GetLastError(), "Unmmap of shared file %s failed", cache->share_file);
}
return res;
}
int mmc_lock_page(mmap_cache* cache, MU64 p_offset) {
OVERLAPPED lock;
DWORD lock_res, bytesTransfered;
memset(&lock, 0, sizeof(lock));
lock.Offset = (DWORD)(p_offset & 0xffffffff);
lock.OffsetHigh = (DWORD)((p_offset >> 32) & 0xffffffff);
lock.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
if (LockFileEx(cache->fh, 0, 0, cache->c_page_size, 0, &lock) == 0) {
DWORD err = GetLastError();
CloseHandle(lock.hEvent);
_mmc_set_error(cache, err, "LockFileEx failed");
return -1;
}
lock_res = WaitForSingleObjectEx(lock.hEvent, 10000, FALSE);
if (lock_res != WAIT_OBJECT_0 || GetOverlappedResult(cache->fh, &lock, &bytesTransfered, FALSE) == FALSE) {
DWORD err = GetLastError();
CloseHandle(lock.hEvent);
_mmc_set_error(cache, err, "Overlapped Lock failed");
return -1;
}
/* Always close the event handle once the lock has been acquired,
* otherwise long-running processes leak one HANDLE per lock. */
CloseHandle(lock.hEvent);
return 0;
}
int mmc_unlock_page(mmap_cache* cache, MU64 p_offset) {
OVERLAPPED lock;
memset(&lock, 0, sizeof(lock));
/* Offset is a DWORD so we must split p_offset across Offset/OffsetHigh,
* otherwise we'd unlock at a different offset than we locked at for
* any cache file larger than 4GB. */
lock.Offset = (DWORD)(p_offset & 0xffffffff);
lock.OffsetHigh = (DWORD)((p_offset >> 32) & 0xffffffff);
lock.hEvent = 0;
UnlockFileEx(cache->fh, 0, cache->c_page_size, 0, &lock);
return 0;
}
/*
* int _mmc_set_error(mmap_cache *cache, int err, char * error_string, ...)
*
* Set internal error string/state
*
*/
int _mmc_set_error(mmap_cache *cache, int err, char * error_string, ...) {
va_list ap;
static char errbuf[1024];
char *msgBuff;
va_start(ap, error_string);
/* Make sure it's terminated */
errbuf[1023] = '\0';
/* Start with error string passed */
vsnprintf(errbuf, 1023, error_string, ap);
/* Add system error code if passed. */
if (err) {
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
err,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
(LPTSTR) &msgBuff,
0, NULL );
if (msgBuff) {
size_t used = strlen(errbuf);
if (used < sizeof(errbuf) - 1) {
snprintf(errbuf + used, sizeof(errbuf) - used, ": %s", msgBuff);
}
LocalFree(msgBuff);
}
}
/* Save in cache object */
cache->last_error = errbuf;
va_end(ap);
return -1;
}
( run in 1.555 second using v1.01-cache-2.11-cpan-bbe5e583499 )