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