APR_DECLARE(apr_status_t) apr_proc_mutex_child_init(apr_proc_mutex_t **mutex, const char *fname, apr_pool_t *pool) { HANDLE hMutex; void *mutexkey; if (!fname) { /* Reinitializing unnamed mutexes is a noop in the Unix code. */ return APR_SUCCESS; } /* res_name_from_filename turns file into a pseudo-name * without slashes or backslashes, and prepends the \global * prefix on Win2K and later */ mutexkey = res_name_from_filename(fname, 1, pool); #if defined(_WIN32_WCE) hMutex = CreateMutex(NULL, FALSE, mutexkey); if (hMutex && ERROR_ALREADY_EXISTS != GetLastError()) { CloseHandle(hMutex); hMutex = NULL; SetLastError(ERROR_FILE_NOT_FOUND); } #else #if APR_HAS_UNICODE_FS IF_WIN_OS_IS_UNICODE { hMutex = OpenMutexW(MUTEX_ALL_ACCESS, FALSE, mutexkey); } #endif #if APR_HAS_ANSI_FS ELSE_WIN_OS_IS_ANSI { hMutex = OpenMutexA(MUTEX_ALL_ACCESS, FALSE, mutexkey); } #endif #endif if (!hMutex) { return apr_get_os_error(); } *mutex = (apr_proc_mutex_t *)apr_palloc(pool, sizeof(apr_proc_mutex_t)); (*mutex)->pool = pool; (*mutex)->handle = hMutex; (*mutex)->fname = fname; apr_pool_cleanup_register((*mutex)->pool, *mutex, proc_mutex_cleanup, apr_pool_cleanup_null); return APR_SUCCESS; }
APR_DECLARE(apr_status_t) apr_proc_mutex_create(apr_proc_mutex_t **mutex, const char *fname, apr_lockmech_e mech, apr_pool_t *pool) { HANDLE hMutex; void *mutexkey; if (mech != APR_LOCK_DEFAULT) { return APR_ENOTIMPL; } /* res_name_from_filename turns fname into a pseduo-name * without slashes or backslashes, and prepends the \global * prefix on Win2K and later */ if (fname) { mutexkey = res_name_from_filename(fname, 1, pool); } else { mutexkey = NULL; } #if APR_HAS_UNICODE_FS IF_WIN_OS_IS_UNICODE { hMutex = CreateMutexW(NULL, FALSE, mutexkey); } #endif #if APR_HAS_ANSI_FS ELSE_WIN_OS_IS_ANSI { hMutex = CreateMutexA(NULL, FALSE, mutexkey); } #endif if (!hMutex) { return apr_get_os_error(); } *mutex = (apr_proc_mutex_t *)apr_palloc(pool, sizeof(apr_proc_mutex_t)); (*mutex)->pool = pool; (*mutex)->handle = hMutex; (*mutex)->fname = fname; apr_pool_cleanup_register((*mutex)->pool, *mutex, proc_mutex_cleanup, apr_pool_cleanup_null); return APR_SUCCESS; }
APR_DECLARE(apr_status_t) apr_shm_create(apr_shm_t **m, apr_size_t reqsize, const char *file, apr_pool_t *pool) { static apr_size_t memblock = 0; HANDLE hMap, hFile; apr_status_t rv; apr_size_t size; apr_file_t *f; void *base; void *mapkey; DWORD err, sizelo, sizehi; reqsize += sizeof(memblock_t); if (!memblock) { SYSTEM_INFO si; GetSystemInfo(&si); memblock = si.dwAllocationGranularity; } /* Compute the granualar multiple of the pagesize */ size = memblock * (1 + (reqsize - 1) / memblock); sizelo = (DWORD)size; #ifdef _WIN64 sizehi = (DWORD)(size >> 32); #else sizehi = 0; #endif if (!file) { /* Do Anonymous, which must be passed as a duplicated handle */ #ifndef _WIN32_WCE hFile = INVALID_HANDLE_VALUE; #endif mapkey = NULL; } 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. */ rv = apr_file_open(&f, file, APR_READ | APR_WRITE | APR_BINARY | APR_CREATE, APR_UREAD | APR_UWRITE, pool); if ((rv != APR_SUCCESS) || ((rv = apr_os_file_get(&hFile, f)) != APR_SUCCESS)) { return rv; } rv = apr_file_trunc(f, size); /* 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_filename(file, 1, pool); } #if APR_HAS_UNICODE_FS IF_WIN_OS_IS_UNICODE { hMap = CreateFileMappingW(hFile, NULL, PAGE_READWRITE, sizehi, sizelo, mapkey); } #endif #if APR_HAS_ANSI_FS ELSE_WIN_OS_IS_ANSI { hMap = CreateFileMappingA(hFile, NULL, PAGE_READWRITE, sizehi, sizelo, mapkey); } #endif err = apr_get_os_error(); if (file) { apr_file_close(f); } if (hMap && APR_STATUS_IS_EEXIST(err)) { CloseHandle(hMap); return APR_EEXIST; } if (!hMap) { return err; } base = MapViewOfFile(hMap, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, size); if (!base) { CloseHandle(hMap); return apr_get_os_error(); } *m = (apr_shm_t *) apr_palloc(pool, sizeof(apr_shm_t)); (*m)->pool = pool; (*m)->hMap = hMap; (*m)->memblk = base; (*m)->size = size; (*m)->usrmem = (char*)base + sizeof(memblock_t); (*m)->length = reqsize - sizeof(memblock_t);; (*m)->memblk->length = (*m)->length; (*m)->memblk->size = (*m)->size; (*m)->filename = file ? apr_pstrdup(pool, file) : NULL; apr_pool_cleanup_register((*m)->pool, *m, shm_cleanup, apr_pool_cleanup_null); return APR_SUCCESS; }
APR_DECLARE(apr_status_t) apr_shm_attach(apr_shm_t **m, const char *file, apr_pool_t *pool) { HANDLE hMap; void *mapkey; void *base; if (!file) { return APR_EINVAL; } else { /* 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_filename(file, 1, pool); } #if APR_HAS_UNICODE_FS IF_WIN_OS_IS_UNICODE { #ifndef _WIN32_WCE hMap = OpenFileMappingW(FILE_MAP_READ | FILE_MAP_WRITE, FALSE, mapkey); #else /* The WCE 3.0 lacks OpenFileMapping. So we emulate one with * opening the existing shmem and reading its size from the header */ hMap = CreateFileMappingW(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, sizeof(apr_shm_t), mapkey); #endif } #endif #if APR_HAS_ANSI_FS ELSE_WIN_OS_IS_ANSI { hMap = OpenFileMappingA(FILE_MAP_READ | FILE_MAP_WRITE, FALSE, mapkey); } #endif if (!hMap) { return apr_get_os_error(); } base = MapViewOfFile(hMap, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0); if (!base) { CloseHandle(hMap); return apr_get_os_error(); } *m = (apr_shm_t *) apr_palloc(pool, sizeof(apr_shm_t)); (*m)->pool = pool; (*m)->memblk = base; /* Real (*m)->mem->size could be recovered with VirtualQuery */ (*m)->size = (*m)->memblk->size; #if _WIN32_WCE /* Reopen with real size */ UnmapViewOfFile(base); CloseHandle(hMap); hMap = CreateFileMappingW(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE, 0, (*m)->size, mapkey); if (!hMap) { return apr_get_os_error(); } base = MapViewOfFile(hMap, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0); if (!base) { CloseHandle(hMap); return apr_get_os_error(); } #endif (*m)->hMap = hMap; (*m)->length = (*m)->memblk->length; (*m)->usrmem = (char*)base + sizeof(memblock_t); (*m)->filename = NULL; apr_pool_cleanup_register((*m)->pool, *m, shm_cleanup, apr_pool_cleanup_null); return APR_SUCCESS; }