r34729 - in /branches/upstream/libcache-fastmmap-perl/current: ./ Cache-FastMmap-CImpl/ t/
eloy at users.alioth.debian.org
eloy at users.alioth.debian.org
Mon May 4 08:33:08 UTC 2009
Author: eloy
Date: Mon May 4 08:32:28 2009
New Revision: 34729
URL: http://svn.debian.org/wsvn/pkg-perl/?sc=1&rev=34729
Log:
[svn-upgrade] Integrating new upstream version, libcache-fastmmap-perl (1.29)
Added:
branches/upstream/libcache-fastmmap-perl/current/Cache-FastMmap-CImpl/mmap_cache_internals.h
branches/upstream/libcache-fastmmap-perl/current/Cache-FastMmap-CImpl/unix.c
branches/upstream/libcache-fastmmap-perl/current/Cache-FastMmap-CImpl/win32.c
Modified:
branches/upstream/libcache-fastmmap-perl/current/Cache-FastMmap-CImpl/CImpl.pm
branches/upstream/libcache-fastmmap-perl/current/Cache-FastMmap-CImpl/Makefile.PL
branches/upstream/libcache-fastmmap-perl/current/Cache-FastMmap-CImpl/README
branches/upstream/libcache-fastmmap-perl/current/Cache-FastMmap-CImpl/mmap_cache.c
branches/upstream/libcache-fastmmap-perl/current/Cache-FastMmap-CImpl/mmap_cache_test.c
branches/upstream/libcache-fastmmap-perl/current/Changes
branches/upstream/libcache-fastmmap-perl/current/FastMmap.pm
branches/upstream/libcache-fastmmap-perl/current/MANIFEST
branches/upstream/libcache-fastmmap-perl/current/META.yml
branches/upstream/libcache-fastmmap-perl/current/README
branches/upstream/libcache-fastmmap-perl/current/t/2.t
Modified: branches/upstream/libcache-fastmmap-perl/current/Cache-FastMmap-CImpl/CImpl.pm
URL: http://svn.debian.org/wsvn/pkg-perl/branches/upstream/libcache-fastmmap-perl/current/Cache-FastMmap-CImpl/CImpl.pm?rev=34729&op=diff
==============================================================================
--- branches/upstream/libcache-fastmmap-perl/current/Cache-FastMmap-CImpl/CImpl.pm (original)
+++ branches/upstream/libcache-fastmmap-perl/current/Cache-FastMmap-CImpl/CImpl.pm Mon May 4 08:32:28 2009
@@ -15,7 +15,7 @@
use strict;
use warnings;
-our $VERSION = '1.28';
+our $VERSION = '1.29';
require XSLoader;
XSLoader::load('Cache::FastMmap::CImpl', $VERSION);
Modified: branches/upstream/libcache-fastmmap-perl/current/Cache-FastMmap-CImpl/Makefile.PL
URL: http://svn.debian.org/wsvn/pkg-perl/branches/upstream/libcache-fastmmap-perl/current/Cache-FastMmap-CImpl/Makefile.PL?rev=34729&op=diff
==============================================================================
--- branches/upstream/libcache-fastmmap-perl/current/Cache-FastMmap-CImpl/Makefile.PL (original)
+++ branches/upstream/libcache-fastmmap-perl/current/Cache-FastMmap-CImpl/Makefile.PL Mon May 4 08:32:28 2009
@@ -7,6 +7,6 @@
'VERSION_FROM' => 'CImpl.pm',
'LIBS' => [''],
'INC' => '-I.',
- 'OBJECT' => 'CImpl.o mmap_cache.o',
+ 'OBJECT' => 'CImpl.o mmap_cache.o ' . ($^O eq 'MSWin32' ? 'win32.o' : 'unix.o'),
# 'DEFINE' => '-DDEBUG',
);
Modified: branches/upstream/libcache-fastmmap-perl/current/Cache-FastMmap-CImpl/README
URL: http://svn.debian.org/wsvn/pkg-perl/branches/upstream/libcache-fastmmap-perl/current/Cache-FastMmap-CImpl/README?rev=34729&op=diff
==============================================================================
--- branches/upstream/libcache-fastmmap-perl/current/Cache-FastMmap-CImpl/README (original)
+++ branches/upstream/libcache-fastmmap-perl/current/Cache-FastMmap-CImpl/README Mon May 4 08:32:28 2009
@@ -22,7 +22,7 @@
COPYRIGHT AND LICENCE
-Copyright (C) 2003-2007 by FastMail IP Partners
+Copyright (C) 2003-2009 by FastMail IP Partners
This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself.
Modified: branches/upstream/libcache-fastmmap-perl/current/Cache-FastMmap-CImpl/mmap_cache.c
URL: http://svn.debian.org/wsvn/pkg-perl/branches/upstream/libcache-fastmmap-perl/current/Cache-FastMmap-CImpl/mmap_cache.c?rev=34729&op=diff
==============================================================================
--- branches/upstream/libcache-fastmmap-perl/current/Cache-FastMmap-CImpl/mmap_cache.c (original)
+++ branches/upstream/libcache-fastmmap-perl/current/Cache-FastMmap-CImpl/mmap_cache.c Mon May 4 08:32:28 2009
@@ -16,112 +16,11 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
-#include <unistd.h>
-#include <fcntl.h>
-#include <sys/mman.h>
-#include <sys/types.h>
-#include <sys/stat.h>
#include <time.h>
#include <errno.h>
#include <stdarg.h>
#include "mmap_cache.h"
-
-#ifdef DEBUG
-#define ASSERT(x) assert(x)
-#include <assert.h>
-#else
-#define ASSERT(x)
-#endif
-
-/* Cache structure */
-struct mmap_cache {
-
- /* Current page details */
- void * p_base;
- MU32 * p_base_slots;
- MU32 p_cur;
- MU32 p_offset;
-
- MU32 p_num_slots;
- MU32 p_free_slots;
- MU32 p_old_slots;
- MU32 p_free_data;
- MU32 p_free_bytes;
- MU32 p_n_reads;
- MU32 p_n_read_hits;
-
- int p_changed;
-
- /* General page details */
- MU32 c_num_pages;
- MU32 c_page_size;
- MU32 c_size;
-
- /* Pointer to mmapped area */
- void * mm_var;
-
- /* Cache general details */
- MU32 start_slots;
- MU32 expire_time;
- int enable_stats;
-
- /* Share mmap file details */
- int fh;
- char * share_file;
- int init_file;
- int test_file;
- int cache_not_found;
-
- /* Last error string */
- char * last_error;
-
-};
-
-struct mmap_cache_it {
- mmap_cache * cache;
- MU32 p_cur;
- MU32 * slot_ptr;
- MU32 * slot_ptr_end;
-};
-
-/* Macros to access page entries */
-#define PP(p) ((MU32 *)p)
-
-#define P_Magic(p) (*(PP(p)+0))
-#define P_NumSlots(p) (*(PP(p)+1))
-#define P_FreeSlots(p) (*(PP(p)+2))
-#define P_OldSlots(p) (*(PP(p)+3))
-#define P_FreeData(p) (*(PP(p)+4))
-#define P_FreeBytes(p) (*(PP(p)+5))
-#define P_NReads(p) (*(PP(p)+6))
-#define P_NReadHits(p) (*(PP(p)+7))
-
-#define P_HEADERSIZE 32
-
-/* Macros to access cache slot entries */
-#define SP(s) ((MU32 *)s)
-
-/* Offset pointer 'p' by 'o' bytes */
-#define PTR_ADD(p,o) ((void *)((char *)p + o))
-
-/* Given a data pointer, get key len, value len or combined len */
-#define S_Ptr(b,s) ((MU32 *)PTR_ADD(b, s))
-
-#define S_LastAccess(s) (*(s+0))
-#define S_ExpireTime(s) (*(s+1))
-#define S_SlotHash(s) (*(s+2))
-#define S_Flags(s) (*(s+3))
-#define S_KeyLen(s) (*(s+4))
-#define S_ValLen(s) (*(s+5))
-
-#define S_KeyPtr(s) ((void *)(s+6))
-#define S_ValPtr(s) (PTR_ADD((void *)(s+6), S_KeyLen(s)))
-
-/* Length of slot data including key and value data */
-#define S_SlotLen(s) (sizeof(MU32)*6 + S_KeyLen(s) + S_ValLen(s))
-#define KV_SlotLen(k,v) (sizeof(MU32)*6 + k + v)
-/* Found key/val len to nearest 4 bytes */
-#define ROUNDLEN(l) ((l) += 3 - (((l)-1) & 3))
+#include "mmap_cache_internals.h"
/* Default values for a new cache */
char * def_share_file = "/tmp/sharefile";
@@ -154,7 +53,7 @@
cache->expire_time = def_expire_time;
cache->fh = 0;
- cache->share_file = def_share_file;
+ cache->share_file = _mmc_get_def_share_filename(cache);
cache->init_file = def_init_file;
cache->test_file = def_test_file;
@@ -211,10 +110,8 @@
*
*/
int mmc_init(mmap_cache * cache) {
- int i, res, fh, do_init;
- void * mm_var, * tmp;
+ int i, do_init;
MU32 c_num_pages, c_page_size, c_size, start_slots;
- struct stat statbuf;
/* Need a share file */
if (!cache->share_file) {
@@ -234,92 +131,18 @@
cache->c_size = c_size = c_num_pages * c_page_size;
- /* 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 != 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;
- }
+ if ( mmc_open_cache_file(cache, &do_init) == -1) return -1;
/* Map file into memory */
- mm_var = mmap(0, c_size, PROT_READ | PROT_WRITE, MAP_SHARED, fh, 0);
- if (mm_var == (void *)MAP_FAILED) {
- close(fh);
- _mmc_set_error(cache, errno, "Mmap of shared file %s failed", cache->share_file);
- return -1;
- }
-
- cache->fh = fh;
- cache->mm_var = mm_var;
+ if ( mmc_map_memory(cache) == -1) return -1;
/* Initialise pages if new file */
if (do_init) {
_mmc_init_page(cache, -1);
/* Unmap and re-map to stop gtop telling us our memory usage is up */
- 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;
- }
-
- mm_var = mmap(0, c_size, PROT_READ | PROT_WRITE, MAP_SHARED, fh, 0);
- if (mm_var == (void *)MAP_FAILED) {
- close(fh);
- _mmc_set_error(cache, errno, "Mmap of shared file %s failed", cache->share_file);
- return -1;
- }
- cache->mm_var = mm_var;
+ if ( mmc_unmap_memory(cache) == -1) return -1;
+ if ( mmc_map_memory(cache) == -1) return -1;
}
/* Test pages in file if asked */
@@ -382,12 +205,12 @@
/* Close file */
if (cache->fh) {
- close(cache->fh);
+ mmc_close_fh(cache);
}
/* Unmap memory */
if (cache->mm_var) {
- res = munmap(cache->mm_var, cache->c_size);
+ res = mmc_unmap_memory(cache);
if (res == -1) {
_mmc_set_error(cache, errno, "Mmap of shared file %s failed", cache->share_file);
return -1;
@@ -415,10 +238,7 @@
*
*/
int mmc_lock(mmap_cache * cache, MU32 p_cur) {
- struct flock lock;
MU32 p_offset;
- int old_alarm, alarm_left = 10;
- int lock_res = -1;
void * p_ptr;
/* Check not already locked */
@@ -428,40 +248,8 @@
/* Setup page details */
p_offset = p_cur * cache->c_page_size;
p_ptr = PTR_ADD(cache->mm_var, p_offset);
-
- /* 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;
-
- 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) {
- alarm(old_alarm);
- break;
- }
-
- /* Turn off alarm for a moment */
- alarm_left = alarm(0);
-
- /* Some signal interrupted, and it wasn't the alarm? Rerun lock */
- if (lock_res == -1 && errno == EINTR && alarm_left) {
- alarm(alarm_left);
- continue;
- }
-
- /* Lock failed? */
- _mmc_set_error(cache, errno, "Lock failed");
- alarm(old_alarm);
- return -1;
- }
+
+ if (mmc_lock_page(cache, p_offset) == -1) return -1;
if (!(P_Magic(p_ptr) == 0x92f7e3b1))
return -1 + _mmc_set_error(cache, 0, "magic page start marker not found. p_cur is %u, offset is %u", p_cur, p_offset);
@@ -512,7 +300,6 @@
*
*/
int mmc_unlock(mmap_cache * cache) {
- struct flock lock;
ASSERT(cache->p_cur != -1);
@@ -533,17 +320,7 @@
/* Test before unlocking */
ASSERT(_mmc_test_page(cache));
- /* Setup fcntl locking structure */
- lock.l_type = F_UNLCK;
- lock.l_whence = SEEK_SET;
- lock.l_start = cache->p_offset;
- lock.l_len = cache->c_page_size;
-
- /* And unlock page */
- fcntl(cache->fh, F_SETLKW, &lock);
-
- /* Set to bad value while page not locked */
- cache->p_cur = -1;
+ mmc_unlock_page(cache);
return 0;
}
@@ -1291,38 +1068,6 @@
P_NReads(p_ptr) = 0;
P_NReadHits(p_ptr) = 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];
-
- 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) {
- strncat(errbuf, ": ", 1024);
- strncat(errbuf, strerror(err), 1023);
- }
-
- /* Save in cache object */
- cache->last_error = errbuf;
-
- va_end(ap);
-
- return 0;
}
/*
@@ -1468,3 +1213,5 @@
}
+
+
Added: branches/upstream/libcache-fastmmap-perl/current/Cache-FastMmap-CImpl/mmap_cache_internals.h
URL: http://svn.debian.org/wsvn/pkg-perl/branches/upstream/libcache-fastmmap-perl/current/Cache-FastMmap-CImpl/mmap_cache_internals.h?rev=34729&op=file
==============================================================================
--- branches/upstream/libcache-fastmmap-perl/current/Cache-FastMmap-CImpl/mmap_cache_internals.h (added)
+++ branches/upstream/libcache-fastmmap-perl/current/Cache-FastMmap-CImpl/mmap_cache_internals.h Mon May 4 08:32:28 2009
@@ -1,0 +1,130 @@
+#ifndef mmap_cache_internals_h
+#define mmap_cache_interanls_h
+
+#ifdef DEBUG
+#define ASSERT(x) assert(x)
+#include <assert.h>
+#else
+#define ASSERT(x)
+#endif
+
+#ifdef WIN32
+#include <windows.h>
+#endif
+
+/* Cache structure */
+struct mmap_cache {
+
+ /* Current page details */
+ void * p_base;
+ MU32 * p_base_slots;
+ MU32 p_cur;
+ MU32 p_offset;
+
+ MU32 p_num_slots;
+ MU32 p_free_slots;
+ MU32 p_old_slots;
+ MU32 p_free_data;
+ MU32 p_free_bytes;
+ MU32 p_n_reads;
+ MU32 p_n_read_hits;
+
+ int p_changed;
+
+ /* General page details */
+ MU32 c_num_pages;
+ MU32 c_page_size;
+ MU32 c_size;
+
+ /* Pointer to mmapped area */
+ void * mm_var;
+
+ /* Cache general details */
+ MU32 start_slots;
+ MU32 expire_time;
+ int enable_stats;
+
+ /* Share mmap file details */
+#ifdef WIN32
+ HANDLE fh;
+#else
+ int fh;
+#endif
+ char * share_file;
+ int init_file;
+ int test_file;
+ int cache_not_found;
+
+ /* Last error string */
+ char * last_error;
+
+};
+
+struct mmap_cache_it {
+ mmap_cache * cache;
+ MU32 p_cur;
+ MU32 * slot_ptr;
+ MU32 * slot_ptr_end;
+};
+
+/* Macros to access page entries */
+#define PP(p) ((MU32 *)p)
+
+#define P_Magic(p) (*(PP(p)+0))
+#define P_NumSlots(p) (*(PP(p)+1))
+#define P_FreeSlots(p) (*(PP(p)+2))
+#define P_OldSlots(p) (*(PP(p)+3))
+#define P_FreeData(p) (*(PP(p)+4))
+#define P_FreeBytes(p) (*(PP(p)+5))
+#define P_NReads(p) (*(PP(p)+6))
+#define P_NReadHits(p) (*(PP(p)+7))
+
+#define P_HEADERSIZE 32
+
+/* Macros to access cache slot entries */
+#define SP(s) ((MU32 *)s)
+
+/* Offset pointer 'p' by 'o' bytes */
+#define PTR_ADD(p,o) ((void *)((char *)p + o))
+
+/* Given a data pointer, get key len, value len or combined len */
+#define S_Ptr(b,s) ((MU32 *)PTR_ADD(b, s))
+
+#define S_LastAccess(s) (*(s+0))
+#define S_ExpireTime(s) (*(s+1))
+#define S_SlotHash(s) (*(s+2))
+#define S_Flags(s) (*(s+3))
+#define S_KeyLen(s) (*(s+4))
+#define S_ValLen(s) (*(s+5))
+
+#define S_KeyPtr(s) ((void *)(s+6))
+#define S_ValPtr(s) (PTR_ADD((void *)(s+6), S_KeyLen(s)))
+
+/* Length of slot data including key and value data */
+#define S_SlotLen(s) (sizeof(MU32)*6 + S_KeyLen(s) + S_ValLen(s))
+#define KV_SlotLen(k,v) (sizeof(MU32)*6 + k + v)
+/* Found key/val len to nearest 4 bytes */
+#define ROUNDLEN(l) ((l) += 3 - (((l)-1) & 3))
+
+/* Externs from mmap_cache.c */
+extern char * def_share_file;
+extern MU32 def_init_file;
+extern MU32 def_test_file;
+extern MU32 def_expire_time;
+extern MU32 def_c_num_pages;
+extern MU32 def_c_page_size;
+extern MU32 def_start_slots;
+extern char* _mmc_get_def_share_filename(mmap_cache * cache);
+
+/* Platform specific functions defined in unix.c | win32.c */
+int mmc_open_cache_file(mmap_cache* cache, int * do_init);
+int mmc_map_memory(mmap_cache* cache);
+int mmc_unmap_memory(mmap_cache* cache);
+int mmc_lock_page(mmap_cache* cache, MU32 p_offset);
+int mmc_unlock_page(mmap_cache * cache);
+int mmc_close_fh(mmap_cache* cache);
+int _mmc_set_error(mmap_cache *cache, int err, char * error_string, ...);
+char* _mmc_get_def_share_filename(mmap_cache * cache);
+
+#endif
+
Modified: branches/upstream/libcache-fastmmap-perl/current/Cache-FastMmap-CImpl/mmap_cache_test.c
URL: http://svn.debian.org/wsvn/pkg-perl/branches/upstream/libcache-fastmmap-perl/current/Cache-FastMmap-CImpl/mmap_cache_test.c?rev=34729&op=diff
==============================================================================
--- branches/upstream/libcache-fastmmap-perl/current/Cache-FastMmap-CImpl/mmap_cache_test.c (original)
+++ branches/upstream/libcache-fastmmap-perl/current/Cache-FastMmap-CImpl/mmap_cache_test.c Mon May 4 08:32:28 2009
@@ -1,13 +1,12 @@
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
+#if !defined(WIN32) || defined(CYGWIN)
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
-#include <sys/wait.h>
#include <fcntl.h>
-#include <time.h>
-#include "mmap_cache.h"
+#endif
#ifdef DEBUG
#define ASSERT(x) assert(x)
@@ -16,6 +15,23 @@
#define ASSERT(x)
#endif
+#ifndef WIN32
+#include <sys/wait.h>
+#else
+#include <stdlib.h>
+#include <stdio.h>
+#include <windows.h>
+double last_rand;
+double drand48(void) {
+ last_rand = rand() / (double)(RAND_MAX+1);
+
+ ASSERT(last_rand < 1);
+ return last_rand;
+}
+#endif
+
+#include <time.h>
+#include "mmap_cache.h"
void * Get(mmap_cache * cache, void * key_ptr, int key_len, int * val_len) {
int found;
@@ -62,7 +78,7 @@
}
/* Get value data pointer */
- mmc_write(cache, hash_slot, key_ptr, key_len, val_ptr, val_len, flags);
+ mmc_write(cache, hash_slot, key_ptr, key_len, val_ptr, val_len, 60, flags);
mmc_unlock(cache);
}
@@ -198,6 +214,9 @@
int urand_fh = 0;
void RandSeed() {
+#ifdef WIN32
+ //randomize();
+#else
char buf[8];
if (!urand_fh) {
@@ -207,6 +226,7 @@
read(urand_fh, buf, 8);
srand48(*(long int *)buf);
+#endif
}
int RepeatMixTests(mmap_cache * cache, double ratio, key_list * kl) {
@@ -282,6 +302,7 @@
}
int ForkTests(mmap_cache * cache, key_list * kl) {
+#ifndef WIN32
int pid, j, k, kid, kids[20], nkids = 0, status;
struct timeval timeout = { 0, 1000 };
@@ -305,6 +326,8 @@
} while (kid > 0 && nkids);
return 0;
+#else
+#endif
}
Added: branches/upstream/libcache-fastmmap-perl/current/Cache-FastMmap-CImpl/unix.c
URL: http://svn.debian.org/wsvn/pkg-perl/branches/upstream/libcache-fastmmap-perl/current/Cache-FastMmap-CImpl/unix.c?rev=34729&op=file
==============================================================================
--- branches/upstream/libcache-fastmmap-perl/current/Cache-FastMmap-CImpl/unix.c (added)
+++ branches/upstream/libcache-fastmmap-perl/current/Cache-FastMmap-CImpl/unix.c Mon May 4 08:32:28 2009
@@ -1,0 +1,230 @@
+
+/*
+ * AUTHOR
+ *
+ * Rob Mueller <cpan at robm.fastmail.fm>
+ *
+ * COPYRIGHT AND LICENSE
+ *
+ * Copyright (C) 2003 by FastMail IP Partners
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the same terms as Perl itself.
+ *
+*/
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <time.h>
+#include <errno.h>
+#include <stdarg.h>
+#include "mmap_cache.h"
+#include "mmap_cache_internals.h"
+
+char* _mmc_get_def_share_filename(mmap_cache * cache)
+{
+ return def_share_file;
+}
+
+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;
+ }
+
+ cache->fh = fh;
+
+ return 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;
+}
+
+/*
+ * 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;
+}
+
+int mmc_close_fh(mmap_cache* cache) {
+ int res = close(cache->fh);
+ return res;
+}
+
+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;
+
+ 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) {
+ alarm(old_alarm);
+ break;
+ }
+
+ /* Turn off alarm for a moment */
+ alarm_left = alarm(0);
+
+ /* Some signal interrupted, and it wasn't the alarm? Rerun lock */
+ if (lock_res == -1 && errno == EINTR && alarm_left) {
+ alarm(alarm_left);
+ continue;
+ }
+
+ /* Lock failed? */
+ _mmc_set_error(cache, errno, "Lock failed");
+ alarm(old_alarm);
+ return -1;
+ }
+
+ return 0;
+}
+
+int mmc_unlock_page(mmap_cache * cache) {
+ struct flock lock;
+
+ /* Setup fcntl locking structure */
+ lock.l_type = F_UNLCK;
+ lock.l_whence = SEEK_SET;
+ lock.l_start = cache->p_offset;
+ lock.l_len = cache->c_page_size;
+
+ /* And unlock page */
+ fcntl(cache->fh, F_SETLKW, &lock);
+
+ /* Set to bad value while page not locked */
+ cache->p_cur = -1;
+
+ 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];
+
+ 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) {
+ strncat(errbuf, ": ", 1024);
+ strncat(errbuf, strerror(err), 1023);
+ }
+
+ /* Save in cache object */
+ cache->last_error = errbuf;
+
+ va_end(ap);
+
+ return 0;
+}
Added: branches/upstream/libcache-fastmmap-perl/current/Cache-FastMmap-CImpl/win32.c
URL: http://svn.debian.org/wsvn/pkg-perl/branches/upstream/libcache-fastmmap-perl/current/Cache-FastMmap-CImpl/win32.c?rev=34729&op=file
==============================================================================
--- branches/upstream/libcache-fastmmap-perl/current/Cache-FastMmap-CImpl/win32.c (added)
+++ branches/upstream/libcache-fastmmap-perl/current/Cache-FastMmap-CImpl/win32.c Mon May 4 08:32:28 2009
@@ -1,0 +1,237 @@
+/*
+ * AUTHOR
+ *
+ * Ash Berlin <ash at cpan.org>
+ *
+ * Based on code by
+ * Rob Mueller <cpan at robm.fastmail.fm>
+ *
+ * COPYRIGHT AND LICENSE
+ *
+ * Copyright (C) 2007 by Ash Berlin
+ *
+ * This library is free software; you can redistribute it and/or modify
+ * it under the same terms as Perl itself.
+ *
+*/
+
+#include <Windows.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <time.h>
+#include <stdarg.h>
+
+
+#include "mmap_cache.h"
+#include "mmap_cache_internals.h"
+
+#ifdef _MSC_VER
+#if _MSC_VER <= 1310
+#define vsnprintf _vsnprintf
+#endif
+#endif
+
+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");
+}
+
+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;
+}
+
+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;
+}
+
+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, 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;
+}
+
+int mmc_unlock_page(mmap_cache* cache) {
+ OVERLAPPED lock;
+ memset(&lock, 0, sizeof(lock));
+ lock.Offset = cache->p_offset;
+ lock.hEvent = 0;
+
+ UnlockFileEx(cache->fh, 0, cache->c_page_size, 0, &lock);
+
+ /* Set to bad value while page not locked */
+ cache->p_cur = ~0; /* ~0 = -1, but unsigned */
+}
+
+/*
+ * 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) {
+ strncat(errbuf, ": ", 1024);
+ FormatMessage(
+ FORMAT_MESSAGE_ALLOCATE_BUFFER |
+ FORMAT_MESSAGE_FROM_SYSTEM,
+ NULL,
+ err,
+ MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
+ (LPTSTR) &msgBuff,
+ 0, NULL );
+ strncat(errbuf, msgBuff, 1023);
+ LocalFree(msgBuff);
+ }
+
+ /* Save in cache object */
+ cache->last_error = errbuf;
+
+ va_end(ap);
+
+ return 0;
+}
+
Modified: branches/upstream/libcache-fastmmap-perl/current/Changes
URL: http://svn.debian.org/wsvn/pkg-perl/branches/upstream/libcache-fastmmap-perl/current/Changes?rev=34729&op=diff
==============================================================================
--- branches/upstream/libcache-fastmmap-perl/current/Changes (original)
+++ branches/upstream/libcache-fastmmap-perl/current/Changes Mon May 4 08:32:28 2009
@@ -1,4 +1,9 @@
Revision history for Perl extension Cache::FastMmap.
+
+1.29 Fri May 1 17:20 2009
+ - Support for Windows (thanks to Ash & kmx.at.volny.cz)
+ (https://rt.cpan.org/Public/Bug/Display.html?id=45210)
+ (https://rt.cpan.org/Public/Bug/Display.html?id=16501)
1.28 Fri Jun 27 11:05 2008
- get_and_set() returns new value + didstore boolean
Modified: branches/upstream/libcache-fastmmap-perl/current/FastMmap.pm
URL: http://svn.debian.org/wsvn/pkg-perl/branches/upstream/libcache-fastmmap-perl/current/FastMmap.pm?rev=34729&op=diff
==============================================================================
--- branches/upstream/libcache-fastmmap-perl/current/FastMmap.pm (original)
+++ branches/upstream/libcache-fastmmap-perl/current/FastMmap.pm Mon May 4 08:32:28 2009
@@ -164,8 +164,10 @@
Cache::FastMmap uses mmap to map a file as the shared cache space,
and fcntl to do page locking. This means it should work on most
-UNIX like operating systems, but will not work on Windows or
-Win32 like environments.
+UNIX like operating systems.
+
+Ash Berlin has written a Win32 layer using MapViewOfFile et al. to
+provide support for Win32 platform.
=head1 MEMORY SIZE
@@ -253,11 +255,13 @@
Create the cache in the parent process, and then when it forks, each
child will inherit the same file descriptor, mmap'ed memory, etc and
-just work.
-
-=item *
-
-Explicitly connect up in each forked child to the share file
+just work. (BEWARE: This works just under UNIX as Win32 has no
+concept of forking)
+
+=item *
+
+Explicitly connect up in each forked child to the share file. (This is
+the only possible way under Win32)
=back
@@ -283,7 +287,7 @@
use warnings;
use bytes;
-our $VERSION = '1.28';
+our $VERSION = '1.29';
use Cache::FastMmap::CImpl;
@@ -300,8 +304,9 @@
=item * B<share_file>
-File to mmap for sharing of data (default on unix: /tmp/sharefile-$pid-$time,
-default on windows: c:\sharefile-$pid-$time)
+File to mmap for sharing of data.
+default on unix: /tmp/sharefile-$pid-$time-$random
+default on windows: %TEMP%\sharefile-$pid-$time-$random
=item * B<init_file>
@@ -488,8 +493,9 @@
my $share_file = $Args{share_file};
if (!$share_file) {
my $tmp_dir = $ENV{TMPDIR} || "/tmp";
- $share_file = ($^O eq "MSWin32" ? "c:\\sharefile" : "$tmp_dir/sharefile");
- $share_file .= "-" . $$ . "-" . time;
+ my $win_tmp_dir = $ENV{TEMP} || "c:\\";
+ $share_file = ($^O eq "MSWin32" ? "$win_tmp_dir\\sharefile" : "$tmp_dir/sharefile");
+ $share_file .= "-" . $$ . "-" . time . "-" . int(rand(100000));
}
!ref($share_file) || die "share_file argument was a reference";
$Self->{share_file} = $share_file;
@@ -1168,6 +1174,15 @@
Otherwise the defaults seem sensible to cleanup unneeded share files rather than
leaving them around to accumulate.
+=item After 1.28
+
+=over 4
+
+=item *
+
+Default share_file name is no longer /tmp/sharefile-$pid-$time
+but /tmp/sharefile-$pid-$time-$random.
+
=back
=back
Modified: branches/upstream/libcache-fastmmap-perl/current/MANIFEST
URL: http://svn.debian.org/wsvn/pkg-perl/branches/upstream/libcache-fastmmap-perl/current/MANIFEST?rev=34729&op=diff
==============================================================================
--- branches/upstream/libcache-fastmmap-perl/current/MANIFEST (original)
+++ branches/upstream/libcache-fastmmap-perl/current/MANIFEST Mon May 4 08:32:28 2009
@@ -2,8 +2,11 @@
Cache-FastMmap-CImpl/CImpl.pm
Cache-FastMmap-CImpl/CImpl.xs
Cache-FastMmap-CImpl/Makefile.PL
+Cache-FastMmap-CImpl/unix.c
+Cache-FastMmap-CImpl/win32.c
Cache-FastMmap-CImpl/mmap_cache.c
Cache-FastMmap-CImpl/mmap_cache.h
+Cache-FastMmap-CImpl/mmap_cache_internals.h
Cache-FastMmap-CImpl/mmap_cache_test.c
Cache-FastMmap-CImpl/ppport.h
Cache-FastMmap-CImpl/README
Modified: branches/upstream/libcache-fastmmap-perl/current/META.yml
URL: http://svn.debian.org/wsvn/pkg-perl/branches/upstream/libcache-fastmmap-perl/current/META.yml?rev=34729&op=diff
==============================================================================
--- branches/upstream/libcache-fastmmap-perl/current/META.yml (original)
+++ branches/upstream/libcache-fastmmap-perl/current/META.yml Mon May 4 08:32:28 2009
@@ -1,7 +1,7 @@
# http://module-build.sourceforge.net/META-spec.html
#XXXXXXX This is a prototype!!! It will change in the future!!! XXXXX#
name: Cache-FastMmap
-version: 1.28
+version: 1.29
version_from: FastMmap.pm
installdirs: site
requires:
Modified: branches/upstream/libcache-fastmmap-perl/current/README
URL: http://svn.debian.org/wsvn/pkg-perl/branches/upstream/libcache-fastmmap-perl/current/README?rev=34729&op=diff
==============================================================================
--- branches/upstream/libcache-fastmmap-perl/current/README (original)
+++ branches/upstream/libcache-fastmmap-perl/current/README Mon May 4 08:32:28 2009
@@ -25,7 +25,7 @@
COPYRIGHT AND LICENCE
-Copyright (C) 2003-2008 by FastMail IP Partners
+Copyright (C) 2003-2009 by FastMail IP Partners
This library is free software; you can redistribute it and/or modify
it under the same terms as Perl itself.
Modified: branches/upstream/libcache-fastmmap-perl/current/t/2.t
URL: http://svn.debian.org/wsvn/pkg-perl/branches/upstream/libcache-fastmmap-perl/current/t/2.t?rev=34729&op=diff
==============================================================================
--- branches/upstream/libcache-fastmmap-perl/current/t/2.t (original)
+++ branches/upstream/libcache-fastmmap-perl/current/t/2.t Mon May 4 08:32:28 2009
@@ -13,7 +13,7 @@
my $FC = Cache::FastMmap->new(init_file => 1, expire_time => 3, raw_values => 1);
ok( defined $FC );
my $FC2 = Cache::FastMmap->new(init_file => 1, expire_time => 5, raw_values => 1);
-ok( defined $FC );
+ok( defined $FC2 );
ok( $FC->set('abc', '123'), "expire set 1");
More information about the Pkg-perl-cvs-commits
mailing list