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

📄 jk_shm.c

📁 jboss与apache集成的中间件,详情请参看文档说明.
💻 C
字号:
/* *  Copyright 1999-2005 The Apache Software Foundation * *  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. *//*************************************************************************** * Description: Shared Memory support                                      * * Author:      Mladen Turk <mturk@jboss.com>                              * * Version:     $Revision: 1.18 $                                          * ***************************************************************************/#include "jk_global.h"#include "jk_pool.h"#include "jk_util.h"#include "jk_mt.h"#include "jk_shm.h"/** jk shm header record structure */struct jk_shm_header{    /* Shared memory magic JK_SHM_MAGIC */    char   magic[8];    size_t size;    size_t pos;    unsigned int childs;    unsigned int workers;    time_t modified;    char   buf[1];};typedef struct jk_shm_header jk_shm_header_t;/** jk shm structure */struct jk_shm{    size_t     size;    const char *filename;    int        fd;    int        fd_lock;    int        attached;    jk_shm_header_t  *hdr;    JK_CRIT_SEC       cs;};typedef struct jk_shm jk_shm_t;static const char shm_signature[] = { JK_SHM_MAGIC };static jk_shm_t jk_shmem = { 0, NULL, -1, -1, 0, NULL};static time_t jk_workers_modified_time = 0;static time_t jk_workers_access_time = 0;#if defined (WIN32) || defined(NETWARE)/* Use plain memory */int jk_shm_open(const char *fname, size_t sz, jk_logger_t *l){    int rc;    JK_TRACE_ENTER(l);    if (jk_shmem.hdr) {        if (JK_IS_DEBUG_LEVEL(l))            jk_log(l, JK_LOG_DEBUG, "Shared memory is already opened");        JK_TRACE_EXIT(l);        return 0;    }    jk_shmem.size =  JK_SHM_ALIGN(sizeof(jk_shm_header_t) + sz);    jk_shmem.hdr = (jk_shm_header_t *)calloc(1, jk_shmem.size);    if (!jk_shmem.hdr) {        JK_TRACE_EXIT(l);        return -1;    }    jk_shmem.filename = "memory";    jk_shmem.fd       = 0;    jk_shmem.attached = 0;    memcpy(jk_shmem.hdr->magic, shm_signature, 8);    jk_shmem.hdr->size = sz;    JK_INIT_CS(&(jk_shmem.cs), rc);    if (JK_IS_DEBUG_LEVEL(l))        jk_log(l, JK_LOG_DEBUG,               "Initialized shared memory size=%u free=%u addr=%#lx",               jk_shmem.size, jk_shmem.hdr->size, jk_shmem.hdr);    JK_TRACE_EXIT(l);    return 0;}int jk_shm_attach(const char *fname, size_t sz, jk_logger_t *l){    JK_TRACE_ENTER(l);    if (!jk_shm_open(fname, sz, l)) {        jk_shmem.attached = 1;        jk_shmem.hdr->childs++;        if (JK_IS_DEBUG_LEVEL(l))            jk_log(l, JK_LOG_DEBUG,                   "Attached shared memory [%d] size=%u free=%u addr=%#lx",                   jk_shmem.hdr->childs, jk_shmem.hdr->size,                   jk_shmem.hdr->size - jk_shmem.hdr->pos,                   jk_shmem.hdr);        JK_TRACE_EXIT(l);        return 0;    }    else {        JK_TRACE_EXIT(l);        return -1;    }}void jk_shm_close(){    if (jk_shmem.hdr) {        int rc;        free(jk_shmem.hdr);        JK_DELETE_CS(&(jk_shmem.cs), rc);    }    jk_shmem.hdr = NULL;}#else#include <unistd.h>#include <fcntl.h>#include <errno.h>#include <sys/stat.h>#include <sys/mman.h>#include <sys/uio.h>#ifndef MAP_FAILED#define MAP_FAILED  (-1)#endif#ifndef MAP_FILE#define MAP_FILE    (0)#endifstatic int do_shm_open_lock(const char *fname, int attached, jk_logger_t *l){    int rc;    int fd;    int flags = O_RDWR;    char flkname[256];    JK_TRACE_ENTER(l);    jk_shmem.fd_lock = -1;    strcpy(flkname, fname);    strcat(flkname, ".lock");    if (!attached)        flags |= (O_CREAT|O_TRUNC);    fd = open(flkname, flags, 0666);    if (fd == -1) {        JK_TRACE_EXIT(l);        return errno;    }    if (!attached) {        if (ftruncate(fd, 1)) {            rc = errno;            close(fd);            JK_TRACE_EXIT(l);            return rc;         }    }    if (lseek(fd, 0, SEEK_SET) != 0) {        rc = errno;        close(fd);        JK_TRACE_EXIT(l);        return rc;    }    jk_shmem.fd_lock = fd;    if (JK_IS_DEBUG_LEVEL(l))        jk_log(l, JK_LOG_DEBUG,               "Opened shared memory lock %s", flkname);    JK_TRACE_EXIT(l);    return 0;}static int do_shm_open(const char *fname, int attached,                       size_t sz, jk_logger_t *l){    int rc;    int fd;    int flags = O_RDWR;    void *base;    JK_TRACE_ENTER(l);    if (jk_shmem.hdr) {        /* Probably a call from vhost */        if (JK_IS_DEBUG_LEVEL(l))            jk_log(l, JK_LOG_DEBUG,                    "Shared memory is already open");        return 0;    }    jk_shmem.filename = fname;    jk_shmem.attached = attached;    jk_shmem.size = JK_SHM_ALIGN(sizeof(jk_shm_header_t) + sz);    /* Use plain memory in case there is no file name */    if (!fname) {        jk_shmem.filename  = "memory";        if (JK_IS_DEBUG_LEVEL(l))            jk_log(l, JK_LOG_DEBUG,                   "Using process memory as shared memory");        JK_TRACE_EXIT(l);        return 0;    }    if (!attached)        flags |= (O_CREAT|O_TRUNC);    fd = open(fname, flags, 0666);    if (fd == -1) {        jk_shmem.size = 0;        JK_TRACE_EXIT(l);        return errno;    }    if (!attached) {        size_t size = lseek(fd, 0, SEEK_END);        if (size < jk_shmem.size) {            size = jk_shmem.size;            if (ftruncate(fd, jk_shmem.size)) {                rc = errno;                close(fd);                jk_shmem.size = 0;                JK_TRACE_EXIT(l);                return rc;            }            if (JK_IS_DEBUG_LEVEL(l))                jk_log(l, JK_LOG_DEBUG,                       "Truncated shared memory to %u", size);        }    }    if (lseek(fd, 0, SEEK_SET) != 0) {        rc = errno;        close(fd);        jk_shmem.size = 0;        JK_TRACE_EXIT(l);        return rc;    }    base = mmap((caddr_t)0, jk_shmem.size,                PROT_READ | PROT_WRITE,                MAP_FILE | MAP_SHARED,                fd, 0);    if (base == (caddr_t)MAP_FAILED || base == (caddr_t)0) {        rc = errno;        close(fd);        jk_shmem.size = 0;        JK_TRACE_EXIT(l);        return rc;    }    jk_shmem.hdr = base;    jk_shmem.fd  = fd;    /* Clear shared memory */    if (!attached) {        memset(jk_shmem.hdr, 0, jk_shmem.size);        memcpy(jk_shmem.hdr->magic, shm_signature, 8);        jk_shmem.hdr->size = sz;        if (JK_IS_DEBUG_LEVEL(l))            jk_log(l, JK_LOG_DEBUG,                   "Initialized shared memory size=%u free=%u addr=%#lx",                   jk_shmem.size, jk_shmem.hdr->size, jk_shmem.hdr);    }    else {        jk_shmem.hdr->childs++;        if (JK_IS_DEBUG_LEVEL(l))            jk_log(l, JK_LOG_INFO,                   "Attached shared memory [%d] size=%u free=%u addr=%#lx",                   jk_shmem.hdr->childs, jk_shmem.hdr->size,                   jk_shmem.hdr->size - jk_shmem.hdr->pos,                   jk_shmem.hdr);        /* TODO: check header magic */    }    JK_INIT_CS(&(jk_shmem.cs), rc);    if ((rc = do_shm_open_lock(fname, attached, l))) {        munmap((void *)jk_shmem.hdr, jk_shmem.size);        close(jk_shmem.fd);        jk_shmem.hdr = NULL;        jk_shmem.fd  = -1;        JK_TRACE_EXIT(l);        return rc;    }    JK_TRACE_EXIT(l);    return 0;}int jk_shm_open(const char *fname, size_t sz, jk_logger_t *l){    return do_shm_open(fname, 0, sz, l);}int jk_shm_attach(const char *fname, size_t sz, jk_logger_t *l){    return do_shm_open(fname, 1, sz, l);}void jk_shm_close(){    int rc;    if (jk_shmem.hdr) {        if (jk_shmem.fd_lock >= 0) {            close(jk_shmem.fd_lock);        }        if (jk_shmem.fd >= 0) {            munmap((void *)jk_shmem.hdr, jk_shmem.size);            close(jk_shmem.fd);        }        jk_shmem.fd_lock = -1;    }    if (jk_shmem.size) {        JK_DELETE_CS(&(jk_shmem.cs), rc);    }    jk_shmem.size = 0;    jk_shmem.hdr  = NULL;    jk_shmem.fd   = -1;}#endifvoid *jk_shm_alloc(jk_pool_t *p, size_t size){    void *rc = NULL;    if (jk_shmem.hdr) {        size = JK_ALIGN_DEFAULT(size);        if ((jk_shmem.hdr->size - jk_shmem.hdr->pos) >= size) {            rc = &(jk_shmem.hdr->buf[jk_shmem.hdr->pos]);            jk_shmem.hdr->pos += size;        }    }    else if (p)        rc = jk_pool_alloc(p, size);    return rc;}const char *jk_shm_name(){    return jk_shmem.filename;}time_t jk_shm_get_workers_time(){    if (jk_shmem.hdr)        return jk_shmem.hdr->modified;    else        return jk_workers_modified_time;}void jk_shm_set_workers_time(time_t t){    if (jk_shmem.hdr)        jk_shmem.hdr->modified = t;    else        jk_workers_modified_time = t;    jk_workers_access_time = t;}int jk_shm_is_modified(){    time_t m = jk_shm_get_workers_time();    if (m != jk_workers_access_time)        return 1;    else        return 0;}void jk_shm_sync_access_time(){    jk_workers_access_time = jk_shm_get_workers_time();}int jk_shm_lock(){    int rc;    JK_ENTER_CS(&(jk_shmem.cs), rc);    if (rc == JK_TRUE && jk_shmem.fd_lock != -1) {        JK_ENTER_LOCK(jk_shmem.fd_lock, rc);    }    return rc;}int jk_shm_unlock(){    int rc;    JK_LEAVE_CS(&(jk_shmem.cs), rc);    if (rc == JK_TRUE && jk_shmem.fd_lock != -1) {        JK_LEAVE_LOCK(jk_shmem.fd_lock, rc);    }    return rc;}jk_shm_worker_t *jk_shm_alloc_worker(jk_pool_t *p){    jk_shm_worker_t *w = (jk_shm_worker_t *)jk_shm_alloc(p, sizeof(jk_shm_worker_t));    if (w) {        memset(w, 0, sizeof(jk_shm_worker_t));        if (jk_shmem.hdr) {            jk_shmem.hdr->workers++;            w->id = jk_shmem.hdr->workers;        }        else            w->id = -1;    }    return w;}

⌨️ 快捷键说明

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