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

📄 shm.c

📁 apache的软件linux版本
💻 C
📖 第 1 页 / 共 2 页
字号:
/* 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 "apr_arch_shm.h"#include "apr_general.h"#include "apr_errno.h"#include "apr_user.h"#include "apr_strings.h"static apr_status_t shm_cleanup_owner(void *m_){    apr_shm_t *m = (apr_shm_t *)m_;    /* anonymous shared memory */    if (m->filename == NULL) {#if APR_USE_SHMEM_MMAP_ZERO || APR_USE_SHMEM_MMAP_ANON        if (munmap(m->base, m->realsize) == -1) {            return errno;        }        return APR_SUCCESS;#endif#if APR_USE_SHMEM_SHMGET_ANON        if (shmdt(m->base) == -1) {            return errno;        }        /* This segment will automatically remove itself after all         * references have detached. */        return APR_SUCCESS;#endif    }    /* name-based shared memory */    else {#if APR_USE_SHMEM_MMAP_TMP        apr_status_t rv;        if (munmap(m->base, m->realsize) == -1) {            return errno;        }        rv = apr_file_remove(m->filename, m->pool);        if (rv != APR_SUCCESS) {            return rv;        }        return APR_SUCCESS;#endif#if APR_USE_SHMEM_MMAP_SHM        if (munmap(m->base, m->realsize) == -1) {            return errno;        }        if (shm_unlink(m->filename) == -1) {            return errno;        }        return APR_SUCCESS;#endif#if APR_USE_SHMEM_SHMGET        apr_status_t rv;        /* Indicate that the segment is to be destroyed as soon         * as all processes have detached. This also disallows any         * new attachments to the segment. */        if (shmctl(m->shmid, IPC_RMID, NULL) == -1) {            return errno;        }        if (shmdt(m->base) == -1) {            return errno;        }        rv = apr_file_remove(m->filename, m->pool);        if (rv != APR_SUCCESS) {            return rv;        }        return APR_SUCCESS;#endif    }    return APR_ENOTIMPL;}APR_DECLARE(apr_status_t) apr_shm_create(apr_shm_t **m,                                         apr_size_t reqsize,                                          const char *filename,                                         apr_pool_t *pool){    apr_shm_t *new_m;    apr_status_t status;#if APR_USE_SHMEM_SHMGET || APR_USE_SHMEM_SHMGET_ANON    struct shmid_ds shmbuf;    apr_uid_t uid;    apr_gid_t gid;#endif#if APR_USE_SHMEM_MMAP_TMP || APR_USE_SHMEM_MMAP_SHM || \    APR_USE_SHMEM_MMAP_ZERO    int tmpfd;#endif#if APR_USE_SHMEM_SHMGET    apr_size_t nbytes;    key_t shmkey;#endif#if APR_USE_SHMEM_MMAP_ZERO || APR_USE_SHMEM_SHMGET || \    APR_USE_SHMEM_MMAP_TMP || APR_USE_SHMEM_MMAP_SHM    apr_file_t *file;   /* file where metadata is stored */#endif    /* Check if they want anonymous or name-based shared memory */    if (filename == NULL) {#if APR_USE_SHMEM_MMAP_ZERO || APR_USE_SHMEM_MMAP_ANON        new_m = apr_palloc(pool, sizeof(apr_shm_t));        if (!new_m) {            return APR_ENOMEM;        }        new_m->pool = pool;        new_m->reqsize = reqsize;        new_m->realsize = reqsize +             APR_ALIGN_DEFAULT(sizeof(apr_size_t)); /* room for metadata */        new_m->filename = NULL;    #if APR_USE_SHMEM_MMAP_ZERO        status = apr_file_open(&file, "/dev/zero", APR_READ | APR_WRITE,                                APR_OS_DEFAULT, pool);        if (status != APR_SUCCESS) {            return status;        }        status = apr_os_file_get(&tmpfd, file);        if (status != APR_SUCCESS) {            return status;        }        new_m->base = mmap(NULL, new_m->realsize, PROT_READ|PROT_WRITE,                           MAP_SHARED, tmpfd, 0);        if (new_m->base == (void *)MAP_FAILED) {            return errno;        }        status = apr_file_close(file);        if (status != APR_SUCCESS) {            return status;        }        /* store the real size in the metadata */        *(apr_size_t*)(new_m->base) = new_m->realsize;        /* metadata isn't usable */        new_m->usable = (char *)new_m->base + APR_ALIGN_DEFAULT(sizeof(apr_size_t));        apr_pool_cleanup_register(new_m->pool, new_m, shm_cleanup_owner,                                  apr_pool_cleanup_null);        *m = new_m;        return APR_SUCCESS;#elif APR_USE_SHMEM_MMAP_ANON        new_m->base = mmap(NULL, new_m->realsize, PROT_READ|PROT_WRITE,                           MAP_ANON|MAP_SHARED, -1, 0);        if (new_m->base == (void *)MAP_FAILED) {            return errno;        }        /* store the real size in the metadata */        *(apr_size_t*)(new_m->base) = new_m->realsize;        /* metadata isn't usable */        new_m->usable = (char *)new_m->base + APR_ALIGN_DEFAULT(sizeof(apr_size_t));        apr_pool_cleanup_register(new_m->pool, new_m, shm_cleanup_owner,                                  apr_pool_cleanup_null);        *m = new_m;        return APR_SUCCESS;#endif /* APR_USE_SHMEM_MMAP_ZERO */#endif /* APR_USE_SHMEM_MMAP_ZERO || APR_USE_SHMEM_MMAP_ANON */#if APR_USE_SHMEM_SHMGET_ANON        new_m = apr_palloc(pool, sizeof(apr_shm_t));        if (!new_m) {            return APR_ENOMEM;        }        new_m->pool = pool;        new_m->reqsize = reqsize;        new_m->realsize = reqsize;        new_m->filename = NULL;        if ((new_m->shmid = shmget(IPC_PRIVATE, new_m->realsize,                                   SHM_R | SHM_W | IPC_CREAT)) < 0) {            return errno;        }        if ((new_m->base = shmat(new_m->shmid, NULL, 0)) == (void *)-1) {            return errno;        }        new_m->usable = new_m->base;        if (shmctl(new_m->shmid, IPC_STAT, &shmbuf) == -1) {            return errno;        }        apr_uid_current(&uid, &gid, pool);        shmbuf.shm_perm.uid = uid;        shmbuf.shm_perm.gid = gid;        if (shmctl(new_m->shmid, IPC_SET, &shmbuf) == -1) {            return errno;        }        /* Remove the segment once use count hits zero.         * We will not attach to this segment again, since it is         * anonymous memory, so it is ok to mark it for deletion.         */        if (shmctl(new_m->shmid, IPC_RMID, NULL) == -1) {            return errno;        }        apr_pool_cleanup_register(new_m->pool, new_m, shm_cleanup_owner,                                  apr_pool_cleanup_null);        *m = new_m;        return APR_SUCCESS;#endif /* APR_USE_SHMEM_SHMGET_ANON */        /* It is an error if they want anonymous memory but we don't have it. */        return APR_ENOTIMPL; /* requested anonymous but we don't have it */    }    /* Name-based shared memory */    else {        new_m = apr_palloc(pool, sizeof(apr_shm_t));        if (!new_m) {            return APR_ENOMEM;        }        new_m->pool = pool;        new_m->reqsize = reqsize;        new_m->filename = apr_pstrdup(pool, filename);#if APR_USE_SHMEM_MMAP_TMP || APR_USE_SHMEM_MMAP_SHM        new_m->realsize = reqsize +             APR_ALIGN_DEFAULT(sizeof(apr_size_t)); /* room for metadata */        /* FIXME: Ignore error for now. *         * status = apr_file_remove(file, pool);*/        status = APR_SUCCESS;    #if APR_USE_SHMEM_MMAP_TMP        /* FIXME: Is APR_OS_DEFAULT sufficient? */        status = apr_file_open(&file, filename,                                APR_READ | APR_WRITE | APR_CREATE | APR_EXCL,                               APR_OS_DEFAULT, pool);        if (status != APR_SUCCESS) {            return status;        }        status = apr_os_file_get(&tmpfd, file);        if (status != APR_SUCCESS) {            apr_file_close(file); /* ignore errors, we're failing */            apr_file_remove(new_m->filename, new_m->pool);            return status;        }        status = apr_file_trunc(file, new_m->realsize);        if (status != APR_SUCCESS) {            apr_file_close(file); /* ignore errors, we're failing */            apr_file_remove(new_m->filename, new_m->pool);            return status;        }        new_m->base = mmap(NULL, new_m->realsize, PROT_READ | PROT_WRITE,                           MAP_SHARED, tmpfd, 0);        /* FIXME: check for errors */        status = apr_file_close(file);        if (status != APR_SUCCESS) {            return status;        }#endif /* APR_USE_SHMEM_MMAP_TMP */#if APR_USE_SHMEM_MMAP_SHM        /* FIXME: Is APR_OS_DEFAULT sufficient? */        tmpfd = shm_open(filename, O_RDWR | O_CREAT | O_EXCL, APR_OS_DEFAULT);        if (tmpfd == -1) {            return errno;        }        status = apr_os_file_put(&file, &tmpfd,

⌨️ 快捷键说明

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