⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 shm.c

📁 linux subdivision ying gai ke yi le ba
💻 C
字号:
/* Copyright 2000-2005 The Apache Software Foundation or its licensors, as * applicable. * * Licensed 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 "apr_general.h"#include "apr_errno.h"#include "apr_file_io.h"#include "apr_shm.h"#include "apr_arch_file_io.h"typedef struct memblock_t {    apr_size_t size;    apr_size_t length;} memblock_t;struct apr_shm_t {    apr_pool_t *pool;    memblock_t *memblk;    void       *usrmem;    apr_size_t  size;    apr_size_t  length;    HANDLE      hMap;};static apr_status_t shm_cleanup(void* shm){    apr_status_t rv = APR_SUCCESS;    apr_shm_t *m = shm;        if (UnmapViewOfFile(m->memblk)) {        rv = apr_get_os_error();    }    if (CloseHandle(m->hMap)) {        return (rv != APR_SUCCESS) ? rv : apr_get_os_error();    }    /* ### Do we want to make a point of unlinking m->file here?      * Need to add the fname to the apr_shm_t, in that case.     */    return rv;}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;    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);    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, 0, size, mapkey);    }#endif#if APR_HAS_ANSI_FS    ELSE_WIN_OS_IS_ANSI    {        hMap = CreateFileMappingA(hFile, NULL, PAGE_READWRITE, 0, size, mapkey);    }#endif    err = apr_get_os_error();    if (file) {        apr_file_close(f);    }    if (hMap && err == ERROR_ALREADY_EXISTS) {        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;    apr_pool_cleanup_register((*m)->pool, *m,                               shm_cleanup, apr_pool_cleanup_null);    return APR_SUCCESS;}APR_DECLARE(apr_status_t) apr_shm_destroy(apr_shm_t *m) {    apr_status_t rv = shm_cleanup(m);    apr_pool_cleanup_kill(m->pool, m, shm_cleanup);    return rv;}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);    apr_pool_cleanup_register((*m)->pool, *m,                               shm_cleanup, apr_pool_cleanup_null);    return APR_SUCCESS;}APR_DECLARE(apr_status_t) apr_shm_detach(apr_shm_t *m){    apr_status_t rv = shm_cleanup(m);    apr_pool_cleanup_kill(m->pool, m, shm_cleanup);    return rv;}APR_DECLARE(void *) apr_shm_baseaddr_get(const apr_shm_t *m){    return m->usrmem;}APR_DECLARE(apr_size_t) apr_shm_size_get(const apr_shm_t *m){    return m->length;}APR_POOL_IMPLEMENT_ACCESSOR(shm)APR_DECLARE(apr_status_t) apr_os_shm_get(apr_os_shm_t *osshm,                                         apr_shm_t *shm){    *osshm = shm->hMap;    return APR_SUCCESS;}APR_DECLARE(apr_status_t) apr_os_shm_put(apr_shm_t **m,                                         apr_os_shm_t *osshm,                                         apr_pool_t *pool){    void* base;    base = MapViewOfFile(*osshm, FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);    if (!base) {        return apr_get_os_error();    }        *m = (apr_shm_t *) apr_palloc(pool, sizeof(apr_shm_t));    (*m)->pool = pool;    (*m)->hMap = *osshm;    (*m)->memblk = base;    (*m)->usrmem = (char*)base + sizeof(memblock_t);    /* Real (*m)->mem->size could be recovered with VirtualQuery */    (*m)->size = (*m)->memblk->size;    (*m)->length = (*m)->memblk->length;    apr_pool_cleanup_register((*m)->pool, *m,                               shm_cleanup, apr_pool_cleanup_null);    return APR_SUCCESS;}    

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -