Exemple #1
0
int mmc_map_memory(mmap_cache * cache) {
    HANDLE fileMap = CreateFileMapping(cache->fh, NULL, PAGE_READWRITE, 0, cache->c_size, NULL);
    if (fileMap == NULL) {
        _mmc_set_error(cache, GetLastError(), "CreateFileMapping of %s failed", cache->share_file);
        CloseHandle(cache->fh);
        return -1;
    }
    
    cache->mm_var = MapViewOfFile(fileMap, FILE_MAP_WRITE|FILE_MAP_READ, 0,0,0);
    if (cache->mm_var == NULL) {
        _mmc_set_error(cache, GetLastError(), "Mmap of shared file %s failed", cache->share_file);
        CloseHandle(fileMap);
        CloseHandle(cache->fh);
        return -1;
        
    }
    /* If I read the docs right, this will do nothing untill the mm_var is unmapped */
    if (CloseHandle(fileMap) == FALSE) {
        _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;
}
Exemple #2
0
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;
}
Exemple #3
0
/*
 * mmc_unmap_memory(mmap_cache * cache)
 *
 * Unmaps cache->mm_var
*/
int mmc_unmap_memory(mmap_cache* cache) {
  int res = munmap(cache->mm_var, cache->c_size);
  if (res == -1) {
    _mmc_set_error(cache, errno, "Munmap of shared file %s failed", cache->share_file);
    return -1;
  }
  return res;
}
Exemple #4
0
/*
 * mmc_map_memory(mmap_cache * cache)
 *
 * maps the cache file into memory, and sets cache->mm_var as needed.
*/
int mmc_map_memory(mmap_cache* cache) {
  /* Map file into memory */
  cache->mm_var = mmap(0, cache->c_size, PROT_READ | PROT_WRITE, MAP_SHARED, cache->fh, 0);
  if (cache->mm_var == (void *)MAP_FAILED) {
    mmc_close_fh(cache);
    _mmc_set_error(cache, errno, "Mmap of shared file %s failed", cache->share_file);
    return -1;
  }

  return 0;
}
Exemple #5
0
int mmc_lock_page(mmap_cache* cache, MU32 p_offset) {
    OVERLAPPED lock;
    DWORD lock_res, bytesTransfered;
    memset(&lock, 0, sizeof(lock));
    lock.Offset = p_offset;
    lock.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
  
    if (LockFileEx(cache->fh, 0, 0, cache->c_page_size, 0, &lock) == 0) {
        _mmc_set_error(cache, GetLastError(), "LockFileEx failed");
        return -1;
    }
    
    lock_res = WaitForSingleObjectEx(lock.hEvent, 10000, FALSE);
    
    if (lock_res != WAIT_OBJECT_0 || GetOverlappedResult(cache->fh, &lock, &bytesTransfered, FALSE) == FALSE) {
        CloseHandle(lock.hEvent);
        _mmc_set_error(cache, GetLastError(), "Overlapped Lock failed");
        return -1;
    }
  return 0;
}
Exemple #6
0
char* _mmc_get_def_share_filename(mmap_cache * cache)
{
    int ret;
    static char buf[MAX_PATH];

    ret = GetTempPath(MAX_PATH, buf);
    if (ret > MAX_PATH)
    {
        _mmc_set_error(cache, GetLastError(), "Unable to get temp path");
        return NULL;
    }    
    return strcat(buf, "sharefile");    
}
Exemple #7
0
int mmc_lock_page(mmap_cache* cache, MU32 p_offset) {
  struct flock lock;
  int old_alarm, alarm_left = 10;
  int lock_res = -1;

  /* Setup fcntl locking structure */
  lock.l_type = F_WRLCK;
  lock.l_whence = SEEK_SET;
  lock.l_start = p_offset;
  lock.l_len = cache->c_page_size;

  if (cache->catch_deadlocks)
    old_alarm = alarm(alarm_left);

  while (lock_res != 0) {

    /* Lock the page (block till done, signal, or timeout) */
    lock_res = fcntl(cache->fh, F_SETLKW, &lock);

    /* Continue immediately if success */
    if (lock_res == 0) {
      if (cache->catch_deadlocks)
        alarm(old_alarm);
      break;
    }

    /* Turn off alarm for a moment */
    if (cache->catch_deadlocks)
      alarm_left = alarm(0);

    /* Some signal interrupted, and it wasn't the alarm? Rerun lock */
    if (lock_res == -1 && errno == EINTR && alarm_left) {
      if (cache->catch_deadlocks)
        alarm(alarm_left);
      continue;
    }

    /* Lock failed? */
    _mmc_set_error(cache, errno, "Lock failed");
    if (cache->catch_deadlocks)
      alarm(old_alarm);
    return -1;
  }

  return 0;
}
Exemple #8
0
int mmc_open_cache_file(mmap_cache* cache, int * do_init) {
  int res, i, fh;
  void * tmp;
  struct stat statbuf;

  /* Check if file exists */
  res = stat(cache->share_file, &statbuf);

  /* Remove if different size or remove requested */
  if (!res &&
      (cache->init_file || (statbuf.st_size != cache->c_size))) {
    res = remove(cache->share_file);
    if (res == -1 && errno != ENOENT) {
      _mmc_set_error(cache, errno, "Unlink of existing share file %s failed", cache->share_file);
      return -1;
    }
  }

  /* Create file if it doesn't exist */
  *do_init = 0;
  res = stat(cache->share_file, &statbuf);
  if (res == -1) {
    res = open(cache->share_file, O_WRONLY | O_CREAT | O_EXCL | O_TRUNC | O_APPEND, 0640);
    if (res == -1) {
      _mmc_set_error(cache, errno, "Create of share file %s failed", cache->share_file);
      return -1;
    }

    /* Fill file with 0's */
    tmp = malloc(cache->c_page_size);
    if (!tmp) {
      _mmc_set_error(cache, errno, "Malloc of tmp space failed");
      return -1;
    }

    memset(tmp, 0, cache->c_page_size);
    for (i = 0; i < cache->c_num_pages; i++) {
      int written = write(res, tmp, cache->c_page_size);
      if (written < 0) {
        _mmc_set_error(cache, errno, "Write to share file %s failed", cache->share_file);
        return -1;
      }
      if (written < cache->c_page_size) {
        _mmc_set_error(cache, errno, "Write to share file %s failed; short write (%d of %d bytes written)", cache->share_file, written, cache->c_page_size);
        return -1;
      }
    }
    free(tmp);

    /* Later on initialise page structures */
    *do_init = 1;

    close(res);
  }

  /* Open for reading/writing */
  fh = open(cache->share_file, O_RDWR);
  if (fh == -1) {
    _mmc_set_error(cache, errno, "Open of share file %s failed", cache->share_file);
    return -1;
  }

  /* Automatically close cache fd on exec */
  fcntl(fh, F_SETFD, FD_CLOEXEC);

  cache->fh = fh;

  return 0;

}
Exemple #9
0
int mmc_open_cache_file(mmap_cache* cache, int* do_init) {
  int i;
  void *tmp;
    HANDLE fh, fileMap, findHandle;
    WIN32_FIND_DATA statbuf;

    *do_init = 0;
        
    findHandle = FindFirstFile(cache->share_file, &statbuf);
        
    /* Create file if it doesn't exist */    
    if (findHandle == INVALID_HANDLE_VALUE) {
        fh = CreateFile(cache->share_file, GENERIC_WRITE, FILE_SHARE_WRITE, NULL,
                        CREATE_ALWAYS, FILE_ATTRIBUTE_TEMPORARY, NULL);
                
        if (fh == INVALID_HANDLE_VALUE) {
            _mmc_set_error(cache, GetLastError(), "Create of share file %s failed", cache->share_file);
            return -1;
        }
        
        /* Fill file with 0's */
        tmp = malloc(cache->c_page_size);
        if (!tmp) {
            _mmc_set_error(cache, GetLastError(), "Malloc of tmp space failed");
            return -1;
        }
        
        memset(tmp, 0, cache->c_page_size);
        for (i = 0; i < cache->c_num_pages; i++) {
            DWORD tmpOut;
            WriteFile(fh, tmp, cache->c_page_size, &tmpOut, NULL);
        }
        free(tmp);
        
        /* Later on initialise page structures */
        *do_init = 1;
        
        CloseHandle(fh);
        
    } else {
        FindClose(findHandle);
    
        if (cache->init_file || (statbuf.nFileSizeLow != cache->c_size)) {
            *do_init = 1;
    
            fh = CreateFile(cache->share_file, GENERIC_WRITE, FILE_SHARE_WRITE, NULL,
			    CREATE_ALWAYS, FILE_ATTRIBUTE_TEMPORARY, NULL);
                            
            if (fh == INVALID_HANDLE_VALUE) {
                _mmc_set_error(cache, GetLastError(), "Truncate of existing share file %s failed", cache->share_file);
                return -1;
            }
            CloseHandle(fh);
        }
    }
    
    fh = CreateFile(cache->share_file,         // File Name 
             GENERIC_READ|GENERIC_WRITE,       // Desired Access
             FILE_SHARE_READ|FILE_SHARE_WRITE, // Share mode
             NULL,                             // Security Rights
             OPEN_EXISTING,                    // Creation Mode
             FILE_ATTRIBUTE_TEMPORARY,         // File Attribs
             NULL);                            // Template File    
    
    if (fh == INVALID_HANDLE_VALUE) {
        _mmc_set_error(cache, GetLastError(), "Open of share file \"%s\" failed", cache->share_file);
        return -1;  
    }

    cache->fh = fh;
    return 0;
}