Cache-FastMmap

 view release on metacpan or  search on metacpan

win32.c  view on Meta::CPAN

        _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 )