Author: mturk
Date: Fri Aug  7 11:17:31 2009
New Revision: 801952

URL: http://svn.apache.org/viewvc?rev=801952&view=rev
Log:
Add windows shared memory implementation

Added:
    commons/sandbox/runtime/trunk/src/main/native/os/win32/shm.c   (with props)
    commons/sandbox/runtime/trunk/src/main/native/os/win32/wutil.c   (with 
props)
Modified:
    commons/sandbox/runtime/trunk/src/main/native/Makefile.msc.in
    
commons/sandbox/runtime/trunk/src/main/native/include/arch/windows/acr_arch.h

Modified: commons/sandbox/runtime/trunk/src/main/native/Makefile.msc.in
URL: 
http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/Makefile.msc.in?rev=801952&r1=801951&r2=801952&view=diff
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/Makefile.msc.in (original)
+++ commons/sandbox/runtime/trunk/src/main/native/Makefile.msc.in Fri Aug  7 
11:17:31 2009
@@ -95,12 +95,14 @@
        $(SRCDIR)/os/win32/platform.$(OBJ) \
        $(SRCDIR)/os/win32/os.$(OBJ) \
        $(SRCDIR)/os/win32/ios.$(OBJ) \
+       $(SRCDIR)/os/win32/shm.$(OBJ) \
        $(SRCDIR)/os/win32/syslog.$(OBJ) \
        $(SRCDIR)/os/win32/group.$(OBJ) \
        $(SRCDIR)/os/win32/user.$(OBJ) \
        $(SRCDIR)/os/win32/time.$(OBJ) \
        $(SRCDIR)/os/win32/uuid.$(OBJ) \
        $(SRCDIR)/os/win32/variant.$(OBJ) \
+       $(SRCDIR)/os/win32/wutil.$(OBJ) \
        $(SRCDIR)/os/win32/wusec.$(OBJ)
 
 TEST_OBJS= \

Modified: 
commons/sandbox/runtime/trunk/src/main/native/include/arch/windows/acr_arch.h
URL: 
http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/include/arch/windows/acr_arch.h?rev=801952&r1=801951&r2=801952&view=diff
==============================================================================
--- 
commons/sandbox/runtime/trunk/src/main/native/include/arch/windows/acr_arch.h 
(original)
+++ 
commons/sandbox/runtime/trunk/src/main/native/include/arch/windows/acr_arch.h 
Fri Aug  7 11:17:31 2009
@@ -341,6 +341,7 @@
     return;
 }
 
+wchar_t *res_name_from_filenamew(int,  wchar_t *, const wchar_t *);
 
 /*
  * ---------------------------------------------------------------------

Added: commons/sandbox/runtime/trunk/src/main/native/os/win32/shm.c
URL: 
http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/win32/shm.c?rev=801952&view=auto
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/os/win32/shm.c (added)
+++ commons/sandbox/runtime/trunk/src/main/native/os/win32/shm.c Fri Aug  7 
11:17:31 2009
@@ -0,0 +1,327 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "acr.h"
+#include "acr_private.h"
+#include "acr_arch.h"
+#include "acr_error.h"
+#include "acr_memory.h"
+#include "acr_string.h"
+#include "acr_descriptor.h"
+#include "acr_shm.h"
+
+#define ACR_SHM_OWNER   0
+#define ACR_SHM_CHILD   1
+
+typedef struct memblock_t {
+    acr_size_t size;
+    acr_size_t length;
+} memblock_t;
+
+struct acr_shm_t {
+    memblock_t     *memblk;
+    void           *usrmem;
+    acr_size_t      size;
+    acr_size_t      length;
+    HANDLE          hmap;
+    const wchar_t  *filename;
+};
+
+static int shm_cleanup(void *shm, int type, unsigned int flags)
+{
+    int rc = 0;
+    acr_shm_t *m = (acr_shm_t *)shm;
+
+    if (type != ACR_DT_SHM) {
+        return ACR_EINVAL;
+    }
+    if (!UnmapViewOfFile(m->memblk)) {
+        rc = ACR_GET_OS_ERROR();
+    }
+    if (!CloseHandle(m->hmap) && rc) {
+        rc = ACR_GET_OS_ERROR();
+    }
+    if (m->filename) {
+        /* Remove file if file backed */
+        if (!DeleteFileW(m->filename) && rc)
+            rc = ACR_GET_OS_ERROR();
+    }
+    x_free((void *)(m->filename));
+    x_free(m);
+    return rc;
+}
+
+
+ACR_DECLARE(int) ACR_ShmClose(JNIEnv *_E, int shm)
+{
+    int rv;
+
+    rv = acr_ioh_close(shm);
+    if (rv  && !IS_INVALID_HANDLE(_E)) {
+        if (rv == EACCES)
+            ACR_ThrowException(_E, THROW_NMARK, ACR_EX_ESECURITY, 0);
+        else
+            ACR_ThrowException(_E, THROW_NMARK, ACR_EX_EIO, rv);
+    }
+    return rv;
+}
+
+ACR_DECLARE(int) ACR_ShmRemove(JNIEnv *_E, const acr_pchar_t *filename)
+{
+    int rc = 0;
+    if (!DeleteFileW(filename))
+        rc = ACR_GET_OS_ERROR();
+    return rc;
+}
+
+ACR_DECLARE(int) ACR_ShmCreate(JNIEnv *_E, acr_size_t reqsize,
+                               const acr_pchar_t *filename)
+{
+    static acr_size_t memblock = 0;
+    acr_shm_t *shm = NULL;
+    int         rc;
+    acr_size_t  nbytes;
+    HANDLE      hmap, hfile;
+    void       *base;
+    wchar_t    *mapkey;
+    wchar_t     keybuf[256];
+    DWORD       sizelo, sizehi;
+    LPDWORD     lpdwhi = NULL;
+
+    if (reqsize > ACR_SIZE_T_MAX) {
+        /* Guard against insane sizes */
+        if (!IS_INVALID_HANDLE(_E)) {
+            ACR_ThrowException(_E, THROW_NMARK, ACR_EX_EINVAL, 0);
+        }
+        ACR_SET_OS_ERROR(ACR_EINVAL);
+        return -1;
+    }
+    reqsize += sizeof(memblock_t);
+    if (!memblock) {
+        SYSTEM_INFO si;
+        GetSystemInfo(&si);
+        memblock = si.dwAllocationGranularity;
+    }
+
+    /* Compute the granualar multiple of the pagesize */
+    nbytes = memblock * (1 + (reqsize - 1) / memblock);
+    sizelo = (DWORD)nbytes;
+#ifdef WIN64
+    sizehi = (DWORD)(nbytes >> 32);
+    lpdwhi = &sizehi;
+#else
+    sizehi = 0;
+#endif
+
+    shm = ACR_Calloc(_E, THROW_FMARK, sizeof(acr_shm_t));
+    if (!shm)
+        return -1;
+    /* Check if they want anonymous or name-based shared memory */
+    if (filename == NULL) {
+        hfile  = INVALID_HANDLE_VALUE;
+        mapkey = NULL;
+    }
+    /* Name-based shared memory */
+    else {
+        /* Do file backed, which is not an inherited handle
+         * While we could open APR_EXCL, it doesn't seem that Unix
+         * ever did.  Ignore that error here, but fail later when
+         * we discover we aren't the creator of the file map object.
+         */
+        hfile = CreateFileW(filename,
+                            GENERIC_READ | GENERIC_WRITE,
+                            FILE_SHARE_READ,
+                            NULL,
+                            CREATE_ALWAYS,
+                            FILE_ATTRIBUTE_NORMAL,
+                            NULL);
+        if (hfile == INVALID_HANDLE_VALUE) {
+            rc = ACR_GET_OS_ERROR();
+            goto cleanup;
+        }
+        if (SetFilePointer(hfile, sizelo, lpdwhi, FILE_BEGIN) == 
INVALID_SET_FILE_POINTER) {
+            rc = ACR_GET_OS_ERROR();
+            CloseHandle(hfile);
+            goto cleanup;
+        }
+        /* res_name_from_filename turns file into a pseudo-name
+         * without slashes or backslashes, and prepends the \global
+         * prefix on Win2K and later
+         */
+        mapkey = res_name_from_filenamew(1, keybuf, filename);
+
+    }
+    hmap = CreateFileMappingW(hfile, NULL, PAGE_READWRITE,
+                              sizehi, sizelo, mapkey);
+    rc = GetLastError();
+    if (hfile != INVALID_HANDLE_VALUE)
+        CloseHandle(hfile);
+    if (hmap && rc == ERROR_ALREADY_EXISTS) {
+        CloseHandle(hmap);
+        rc = ACR_EEXIST;
+        goto cleanup;
+    }
+    if (!hmap) {
+        goto cleanup;
+    }
+    base = MapViewOfFile(hmap, FILE_MAP_READ | FILE_MAP_WRITE,
+                         0, 0, nbytes);
+    if (!base) {
+        rc = ACR_GET_OS_ERROR();
+        CloseHandle(hmap);
+        goto cleanup;
+    }
+    shm->hmap   = hmap;
+    shm->memblk = base;
+    shm->size   = nbytes;
+
+    shm->usrmem = (char*)base + sizeof(memblock_t);
+    shm->length = reqsize - sizeof(memblock_t);;
+
+    shm->memblk->length = shm->length;
+    shm->memblk->size   = shm->size;
+    if (filename) {
+        shm->filename = ACR_StrdupW(_E, THROW_FMARK, filename);
+        if (!shm->filename) {
+            rc = ACR_GET_OS_ERROR();
+            goto cleanup;
+        }
+    }
+    else
+        shm->filename = NULL;
+
+cleanup:
+    if (rc) {
+        x_free((void *)(shm->filename));
+        x_free(shm);
+        if (!IS_INVALID_HANDLE(_E)) {
+            if (rc == EACCES)
+                ACR_ThrowException(_E, THROW_NMARK, ACR_EX_ESECURITY, 0);
+            else
+                ACR_ThrowException(_E, THROW_NMARK, ACR_EX_EIO, rc);
+        }
+        ACR_SET_OS_ERROR(rc);
+        shm = NULL;
+    }
+
+    if (shm) {
+        rc = acr_ioh_open(shm, ACR_DT_SHM, ACR_SHM_OWNER, shm_cleanup);
+        return rc;
+    }
+    else
+        return -1;
+}
+
+ACR_DECLARE(int) ACR_ShmAttach(JNIEnv *_E,
+                               const acr_pchar_t *filename)
+{
+    int rc = 0;
+    acr_shm_t *shm = NULL;
+    HANDLE     hmap;
+    wchar_t    mapkey[256];
+    void      *base;
+
+    if (!filename) {
+        ACR_SET_OS_ERROR(ACR_EINVAL);
+        return -1;
+    }
+    shm = ACR_Calloc(_E, THROW_FMARK, sizeof(acr_shm_t));
+    if (!shm)
+        return -1;
+    res_name_from_filenamew(1, mapkey, filename);
+    hmap = OpenFileMappingW(FILE_MAP_READ | FILE_MAP_WRITE, FALSE, mapkey);
+    if (!hmap) {
+        rc = ACR_GET_OS_ERROR();
+        goto cleanup;
+    }
+    base = MapViewOfFile(hmap, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
+    if (!base) {
+        rc = ACR_GET_OS_ERROR();
+        CloseHandle(hmap);
+        goto cleanup;
+    }
+    shm->memblk = base;
+    /* Real shm->mem->size could be recovered with VirtualQuery */
+    shm->size     = shm->memblk->size;
+    shm->hmap     = hmap;
+    shm->length   = shm->memblk->length;
+    shm->usrmem   = (char*)base + sizeof(memblock_t);
+    shm->filename = NULL;
+
+cleanup:
+    if (rc) {
+        free(shm);
+        if (!IS_INVALID_HANDLE(_E)) {
+            if (rc == EACCES)
+                ACR_ThrowException(_E, THROW_NMARK, ACR_EX_ESECURITY, 0);
+            else
+                ACR_ThrowException(_E, THROW_NMARK, ACR_EX_EIO, rc);
+        }
+        ACR_SET_OS_ERROR(rc);
+        shm = NULL;
+    }
+    if (shm) {
+        rc = acr_ioh_open(shm, ACR_DT_SHM, ACR_SHM_CHILD, shm_cleanup);
+        return rc;
+    }
+    else
+        return -1;
+}
+
+ACR_DECLARE(int) ACR_ShmPermSet(JNIEnv *_E, int shm, int perms,
+                                acr_uid_t uid, acr_uid_t gid)
+{
+    int rc = 0;
+    acr_shm_t *m = (acr_shm_t *)ACR_IOH(shm);
+
+    if (IS_INVALID_HANDLE(m) || ACR_IOH_TYPE(shm) != ACR_DT_SHM) {
+        rc = ACR_EINVAL;
+        goto cleanup;
+    }
+
+cleanup:
+    if (rc && !IS_INVALID_HANDLE(_E)) {
+        if (rc == EACCES)
+            ACR_ThrowException(_E, THROW_NMARK, ACR_EX_ESECURITY, 0);
+        else
+            ACR_ThrowException(_E, THROW_NMARK, ACR_EX_EIO, rc);
+    }
+    return rc;
+}
+
+ACR_DECLARE(void *) ACR_ShmGetBaseAddr(int shm)
+{
+    acr_shm_t *m = (acr_shm_t *)ACR_IOH(shm);
+
+    if (IS_INVALID_HANDLE(m) || ACR_IOH_TYPE(shm) != ACR_DT_SHM) {
+        ACR_SET_OS_ERROR(ACR_EINVAL);
+        return NULL;
+    }
+    else
+        return m->usrmem;
+}
+
+ACR_DECLARE(acr_size_t) ACR_ShmGetSize(int shm)
+{
+    acr_shm_t *m = (acr_shm_t *)ACR_IOH(shm);
+    if (IS_INVALID_HANDLE(m) || ACR_IOH_TYPE(shm) != ACR_DT_SHM) {
+        ACR_SET_OS_ERROR(ACR_EINVAL);
+        return 0;
+    }
+    else
+        return m->length;
+}
+

Propchange: commons/sandbox/runtime/trunk/src/main/native/os/win32/shm.c
------------------------------------------------------------------------------
    svn:eol-style = native

Added: commons/sandbox/runtime/trunk/src/main/native/os/win32/wutil.c
URL: 
http://svn.apache.org/viewvc/commons/sandbox/runtime/trunk/src/main/native/os/win32/wutil.c?rev=801952&view=auto
==============================================================================
--- commons/sandbox/runtime/trunk/src/main/native/os/win32/wutil.c (added)
+++ commons/sandbox/runtime/trunk/src/main/native/os/win32/wutil.c Fri Aug  7 
11:17:31 2009
@@ -0,0 +1,52 @@
+/* Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "acr.h"
+#include "acr_private.h"
+#include "acr_arch.h"
+#include "acr_clazz.h"
+#include "acr_error.h"
+#include "acr_memory.h"
+#include "acr_string.h"
+#include "acr_descriptor.h"
+
+wchar_t *res_name_from_filenamew(int global, wchar_t *rname,
+                                 const wchar_t *fname)
+{
+    const wchar_t *prefix;
+    wchar_t       *ch;
+    size_t r, n = wcslen(fname);
+
+    if (global)
+        prefix = L"Global\\";
+    else
+        prefix = L"Local\\";
+    r = wcslen(prefix);
+    if (n > 255 - r) {
+        fname += n - 255 - r;
+        n = 255;
+    }
+    wcscpy(rname, prefix);
+    wcsncat(rname, fname, 255 - r);
+    for (ch = rname + r; *ch; ++ch) {
+        if (*ch == L':' || *ch == L'/' || *ch == L'\\')
+            *ch = L'_';
+        else
+            *ch = towupper(*ch);
+    }
+
+    return rname;
+}

Propchange: commons/sandbox/runtime/trunk/src/main/native/os/win32/wutil.c
------------------------------------------------------------------------------
    svn:eol-style = native


Reply via email to