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