summaryrefslogtreecommitdiffstats
path: root/rubbos/app/tomcat-connectors-1.2.32-src/native/common/jk_shm.c
diff options
context:
space:
mode:
Diffstat (limited to 'rubbos/app/tomcat-connectors-1.2.32-src/native/common/jk_shm.c')
-rw-r--r--rubbos/app/tomcat-connectors-1.2.32-src/native/common/jk_shm.c812
1 files changed, 812 insertions, 0 deletions
diff --git a/rubbos/app/tomcat-connectors-1.2.32-src/native/common/jk_shm.c b/rubbos/app/tomcat-connectors-1.2.32-src/native/common/jk_shm.c
new file mode 100644
index 00000000..1640f474
--- /dev/null
+++ b/rubbos/app/tomcat-connectors-1.2.32-src/native/common/jk_shm.c
@@ -0,0 +1,812 @@
+/*
+ * 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.
+ */
+
+/***************************************************************************
+ * Description: Shared Memory support *
+ * Author: Mladen Turk <mturk@jboss.com> *
+ * Author: Rainer Jung <rjung@apache.org> *
+ * Version: $Revision: 704548 $ *
+ ***************************************************************************/
+
+#include "jk_global.h"
+#include "jk_pool.h"
+#include "jk_util.h"
+#include "jk_mt.h"
+#include "jk_lb_worker.h"
+#include "jk_ajp13_worker.h"
+#include "jk_ajp14_worker.h"
+#include "jk_shm.h"
+
+/** jk shm header core data structure */
+struct jk_shm_header_data
+{
+ /* Shared memory magic JK_SHM_MAGIC */
+ char magic[JK_SHM_MAGIC_SIZ];
+ size_t size;
+ size_t pos;
+ unsigned int childs;
+ unsigned int workers;
+ time_t modified;
+};
+
+typedef struct jk_shm_header_data jk_shm_header_data_t;
+
+/** jk shm header record structure */
+struct jk_shm_header
+{
+ union {
+ jk_shm_header_data_t data;
+ char alignbuf[JK_SHM_ALIGN(sizeof(jk_shm_header_data_t))];
+ } h;
+ char buf[1];
+};
+
+typedef struct jk_shm_header jk_shm_header_t;
+
+/** jk shm structure */
+struct jk_shm
+{
+ size_t size;
+ unsigned ajp_workers;
+ unsigned lb_sub_workers;
+ unsigned lb_workers;
+ char *filename;
+ char *lockname;
+ 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, 0, 0, 0, NULL, NULL, -1, -1, 0, NULL};
+static time_t jk_workers_modified_time = 0;
+static time_t jk_workers_access_time = 0;
+#if defined (WIN32)
+static HANDLE jk_shm_map = NULL;
+static HANDLE jk_shm_hlock = NULL;
+#endif
+
+/* Calculate needed shm size */
+size_t jk_shm_calculate_size(jk_map_t *init_data, jk_logger_t *l)
+{
+ char **worker_list;
+ unsigned i;
+ unsigned num_of_workers;
+ int num_of_ajp_workers = 0;
+ int num_of_lb_sub_workers = 0;
+ int num_of_lb_workers = 0;
+
+ JK_TRACE_ENTER(l);
+
+ if (jk_get_worker_list(init_data, &worker_list,
+ &num_of_workers) == JK_FALSE) {
+ jk_log(l, JK_LOG_ERROR,
+ "Could not get worker list from map");
+ JK_TRACE_EXIT(l);
+ return 0;
+ }
+
+ for (i = 0; i < num_of_workers; i++) {
+ const char *type = jk_get_worker_type(init_data, worker_list[i]);
+
+ if (!strcmp(type, JK_AJP13_WORKER_NAME) ||
+ !strcmp(type, JK_AJP14_WORKER_NAME)) {
+ num_of_ajp_workers++;
+ }
+ else if (!strcmp(type, JK_LB_WORKER_NAME)) {
+ char **member_list;
+ unsigned num_of_members;
+ num_of_lb_workers++;
+ if (jk_get_lb_worker_list(init_data, worker_list[i],
+ &member_list, &num_of_members) == JK_FALSE) {
+ jk_log(l, JK_LOG_ERROR,
+ "Could not get member list for lb worker from map");
+ }
+ else {
+ if (JK_IS_DEBUG_LEVEL(l))
+ jk_log(l, JK_LOG_DEBUG, "worker %s of type %s has %u members",
+ worker_list[i], JK_LB_WORKER_NAME, num_of_members);
+ num_of_lb_sub_workers += num_of_members;
+ }
+ }
+ }
+ if (JK_IS_DEBUG_LEVEL(l))
+ jk_log(l, JK_LOG_DEBUG, "shared memory will contain %d ajp workers of size %d and %d lb workers of size %d with %d members of size %d+%d",
+ num_of_ajp_workers, JK_SHM_AJP_SIZE(1),
+ num_of_lb_workers, JK_SHM_LB_SIZE(1),
+ num_of_lb_sub_workers, JK_SHM_LB_SUB_SIZE(1), JK_SHM_AJP_SIZE(1));
+ jk_shmem.ajp_workers = num_of_ajp_workers;
+ jk_shmem.lb_sub_workers = num_of_lb_sub_workers;
+ jk_shmem.lb_workers = num_of_lb_workers;
+ JK_TRACE_EXIT(l);
+ return JK_SHM_AJP_SIZE(jk_shmem.ajp_workers) +
+ JK_SHM_LB_SUB_SIZE(jk_shmem.lb_sub_workers) +
+ JK_SHM_AJP_SIZE(jk_shmem.lb_sub_workers) +
+ JK_SHM_LB_SIZE(jk_shmem.lb_workers);
+}
+
+
+#if defined (WIN32) || defined(NETWARE)
+
+/* Use plain memory */
+int jk_shm_open(const char *fname, size_t sz, jk_logger_t *l)
+{
+ int rc;
+ int attached = 0;
+ char lkname[MAX_PATH];
+ 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);
+
+#if defined (WIN32)
+ if (fname) {
+ jk_shm_map = CreateFileMapping(INVALID_HANDLE_VALUE,
+ NULL,
+ PAGE_READWRITE,
+ 0,
+ (DWORD)(sizeof(jk_shm_header_t) + sz),
+ fname);
+ if (GetLastError() == ERROR_ALREADY_EXISTS) {
+ attached = 1;
+ if (jk_shm_map == NULL || jk_shm_map == INVALID_HANDLE_VALUE) {
+ jk_shm_map = OpenFileMapping(PAGE_READWRITE, FALSE, fname);
+ }
+ }
+ if (jk_shm_map == NULL || jk_shm_map == INVALID_HANDLE_VALUE) {
+ JK_TRACE_EXIT(l);
+ return -1;
+ }
+ sprintf(lkname, "Global\\%s_MUTEX", fname);
+ if (attached) {
+ jk_shm_hlock = OpenMutex(MUTEX_ALL_ACCESS, FALSE, lkname);
+ }
+ else {
+ jk_shm_hlock = CreateMutex(NULL, FALSE, lkname);
+ }
+ if (jk_shm_hlock == NULL || jk_shm_hlock == INVALID_HANDLE_VALUE) {
+ CloseHandle(jk_shm_map);
+ jk_shm_map = NULL;
+ JK_TRACE_EXIT(l);
+ return -1;
+ }
+ jk_shmem.hdr = (jk_shm_header_t *)MapViewOfFile(jk_shm_map,
+ FILE_MAP_ALL_ACCESS,
+ 0,
+ 0,
+ 0);
+ }
+ else
+#endif
+ jk_shmem.hdr = (jk_shm_header_t *)calloc(1, jk_shmem.size);
+ if (!jk_shmem.hdr) {
+#if defined (WIN32)
+ if (jk_shm_map) {
+ CloseHandle(jk_shm_map);
+ jk_shm_map = NULL;
+ }
+ if (jk_shm_hlock) {
+ CloseHandle(jk_shm_hlock);
+ jk_shm_hlock = NULL;
+ }
+#endif
+ JK_TRACE_EXIT(l);
+ return -1;
+ }
+ if (!jk_shmem.filename) {
+ if (fname)
+ jk_shmem.filename = strdup(fname);
+ else
+ jk_shmem.filename = strdup("memory");
+ }
+ jk_shmem.fd = 0;
+ jk_shmem.attached = attached;
+ if (!attached) {
+ memcpy(jk_shmem.hdr->h.data.magic, shm_signature,
+ JK_SHM_MAGIC_SIZ);
+ jk_shmem.hdr->h.data.size = sz;
+ jk_shmem.hdr->h.data.childs = 1;
+ }
+ else {
+ jk_shmem.hdr->h.data.childs++;
+ /*
+ * Reset the shared memory so that
+ * alloc works even for attached memory.
+ * XXX: This might break already used memory
+ * if the number of workers change between
+ * open and attach or between two attach operations.
+ */
+ if (jk_shmem.hdr->h.data.childs > 1) {
+ if (JK_IS_DEBUG_LEVEL(l)) {
+ jk_log(l, JK_LOG_DEBUG,
+ "Resetting the shared memory for child %d",
+ jk_shmem.hdr->h.data.childs);
+ }
+ }
+ jk_shmem.hdr->h.data.pos = 0;
+ jk_shmem.hdr->h.data.workers = 0;
+ }
+ JK_INIT_CS(&(jk_shmem.cs), rc);
+ if (JK_IS_DEBUG_LEVEL(l))
+ jk_log(l, JK_LOG_DEBUG,
+ "%s shared memory %s size=%u free=%u addr=%#lx",
+ attached ? "Attached" : "Initialized",
+ jk_shm_name(), jk_shmem.size,
+ jk_shmem.hdr->h.data.size - jk_shmem.hdr->h.data.pos,
+ 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)) {
+ if (!jk_shmem.attached) {
+ jk_shmem.attached = 1;
+ if (JK_IS_DEBUG_LEVEL(l)) {
+ jk_log(l, JK_LOG_DEBUG,
+ "Attached shared memory %s [%d] size=%u free=%u addr=%#lx",
+ jk_shm_name(), jk_shmem.hdr->h.data.childs, jk_shmem.size,
+ jk_shmem.hdr->h.data.size - jk_shmem.hdr->h.data.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;
+#if defined (WIN32)
+ if (jk_shm_hlock) {
+ CloseHandle(jk_shm_hlock);
+ jk_shm_hlock = NULL;
+ }
+ if (jk_shm_map) {
+ --jk_shmem.hdr->h.data.childs;
+ UnmapViewOfFile(jk_shmem.hdr);
+ CloseHandle(jk_shm_map);
+ jk_shm_map = NULL;
+ }
+ else
+#endif
+ free(jk_shmem.hdr);
+ JK_DELETE_CS(&(jk_shmem.cs), rc);
+ }
+ jk_shmem.hdr = NULL;
+ if (jk_shmem.filename) {
+ free(jk_shmem.filename);
+ jk_shmem.filename = 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)
+#endif
+
+static int do_shm_open_lock(const char *fname, int attached, jk_logger_t *l)
+{
+ int rc;
+ char flkname[256];
+#ifdef AS400_UTF8
+ char *wptr;
+#endif
+
+ JK_TRACE_ENTER(l);
+
+ if (attached && jk_shmem.lockname) {
+#ifdef JK_SHM_LOCK_REOPEN
+ jk_shmem.fd_lock = open(jk_shmem.lockname, O_RDWR, 0666);
+#else
+ errno = EINVAL;
+#endif
+ if (jk_shmem.fd_lock == -1) {
+ rc = errno;
+ JK_TRACE_EXIT(l);
+ return rc;
+ }
+ if (JK_IS_DEBUG_LEVEL(l))
+ jk_log(l, JK_LOG_DEBUG,
+ "Duplicated shared memory lock %s", jk_shmem.lockname);
+ JK_TRACE_EXIT(l);
+ return 0;
+ }
+
+ if (!jk_shmem.lockname) {
+#ifdef JK_SHM_LOCK_REOPEN
+ int i;
+ jk_shmem.fd_lock = -1;
+ mode_t mask = umask(0);
+ for (i = 0; i < 8; i++) {
+ strcpy(flkname, "/tmp/jkshmlock.XXXXXX");
+ if (mktemp(flkname)) {
+ jk_shmem.fd_lock = open(flkname, O_RDWR|O_CREAT|O_TRUNC, 0666);
+ if (jk_shmem.fd_lock >= 0)
+ break;
+ }
+ }
+ umask(mask);
+#else
+ strcpy(flkname, fname);
+ strcat(flkname, ".lock");
+#ifdef AS400_UTF8
+ wptr = (char *)malloc(strlen(flkname) + 1);
+ jk_ascii2ebcdic((char *)flkname, wptr);
+ jk_shmem.fd_lock = open(wptr, O_RDWR|O_CREAT|O_TRUNC, 0666);
+ free(wptr);
+#else
+ jk_shmem.fd_lock = open(flkname, O_RDWR|O_CREAT|O_TRUNC, 0666);
+#endif
+#endif
+ if (jk_shmem.fd_lock == -1) {
+ rc = errno;
+ JK_TRACE_EXIT(l);
+ return rc;
+ }
+ jk_shmem.lockname = strdup(flkname);
+ }
+ else {
+ /* Nothing to do */
+ JK_TRACE_EXIT(l);
+ return 0;
+ }
+
+ if (ftruncate(jk_shmem.fd_lock, 1)) {
+ rc = errno;
+ close(jk_shmem.fd_lock);
+ jk_shmem.fd_lock = -1;
+ JK_TRACE_EXIT(l);
+ return rc;
+ }
+ if (lseek(jk_shmem.fd_lock, 0, SEEK_SET) != 0) {
+ rc = errno;
+ close(jk_shmem.fd_lock);
+ jk_shmem.fd_lock = -1;
+ return rc;
+ }
+ if (JK_IS_DEBUG_LEVEL(l))
+ jk_log(l, JK_LOG_DEBUG,
+ "Opened shared memory lock %s", jk_shmem.lockname);
+ 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;
+ void *base;
+#ifdef AS400_UTF8
+ char *wptr;
+#endif
+
+ JK_TRACE_ENTER(l);
+ if (jk_shmem.hdr) {
+ /* Probably a call from vhost */
+ if (!attached)
+ attached = 1;
+ }
+ else if (attached) {
+ /* We should already have a header
+ * Use memory if we don't
+ */
+ JK_TRACE_EXIT(l);
+ return 0;
+ }
+ jk_shmem.size = JK_SHM_ALIGN(sizeof(jk_shm_header_t) + sz);
+
+ if (!fname) {
+ /* Use plain memory in case there is no file name */
+ if (!jk_shmem.filename)
+ jk_shmem.filename = strdup("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 (!jk_shmem.filename) {
+ jk_shmem.filename = (char *)malloc(strlen(fname) + 32);
+ sprintf(jk_shmem.filename, "%s.%" JK_PID_T_FMT, fname, getpid());
+ }
+ if (!attached) {
+ size_t size;
+ jk_shmem.attached = 0;
+#ifdef AS400_UTF8
+ wptr = (char *)malloc(strlen(jk_shmem.filename) + 1);
+ jk_ascii2ebcdic((char *)jk_shmem.filename, wptr);
+ fd = open(wptr, O_RDWR|O_CREAT|O_TRUNC, 0666);
+ free(wptr);
+#else
+ fd = open(jk_shmem.filename, O_RDWR|O_CREAT|O_TRUNC, 0666);
+#endif
+ if (fd == -1) {
+ jk_shmem.size = 0;
+ JK_TRACE_EXIT(l);
+ return errno;
+ }
+ 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);
+#ifdef AS400_UTF8
+ wptr = (char *)malloc(strlen(jk_shmem.filename) + 1);
+ jk_ascii2ebcdic((char *)jk_shmem.filename, wptr);
+ unlink(wptr);
+ free(wptr);
+#else
+ unlink(jk_shmem.filename);
+#endif
+ 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);
+#ifdef AS400_UTF8
+ wptr = (char *)malloc(strlen(jk_shmem.filename) + 1);
+ jk_ascii2ebcdic((char *)jk_shmem.filename, wptr);
+ unlink(wptr);
+ free(wptr);
+#else
+ unlink(jk_shmem.filename);
+#endif
+ 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);
+#ifdef AS400_UTF8
+ wptr = (char *)malloc(strlen(jk_shmem.filename) + 1);
+ jk_ascii2ebcdic((char *)jk_shmem.filename, wptr);
+ unlink(wptr);
+ free(wptr);
+#else
+ unlink(jk_shmem.filename);
+#endif
+ jk_shmem.size = 0;
+ JK_TRACE_EXIT(l);
+ return rc;
+ }
+ jk_shmem.hdr = base;
+ jk_shmem.fd = fd;
+ memset(jk_shmem.hdr, 0, jk_shmem.size);
+ memcpy(jk_shmem.hdr->h.data.magic, shm_signature, JK_SHM_MAGIC_SIZ);
+ jk_shmem.hdr->h.data.size = sz;
+ jk_shmem.hdr->h.data.childs = 1;
+ if (JK_IS_DEBUG_LEVEL(l))
+ jk_log(l, JK_LOG_DEBUG,
+ "Initialized shared memory %s size=%u free=%u addr=%#lx",
+ jk_shm_name(), jk_shmem.size,
+ jk_shmem.hdr->h.data.size - jk_shmem.hdr->h.data.pos,
+ jk_shmem.hdr);
+ }
+ else {
+ unsigned int nchild;
+ jk_shmem.hdr->h.data.childs++;
+ jk_shmem.attached = (int)getpid();
+ nchild = jk_shmem.hdr->h.data.childs;
+ if (JK_IS_DEBUG_LEVEL(l))
+ jk_log(l, JK_LOG_DEBUG,
+ "Attached shared memory %s [%d] size=%u free=%u addr=%#lx",
+ jk_shm_name(), nchild, jk_shmem.size,
+ jk_shmem.hdr->h.data.size - jk_shmem.hdr->h.data.pos,
+ jk_shmem.hdr);
+ /*
+ * Reset the shared memory so that
+ * alloc works even for attached memory.
+ * XXX: This might break already used memory
+ * if the number of workers change between
+ * open and attach or between two attach operations.
+ */
+ if (nchild > 1) {
+ if (JK_IS_DEBUG_LEVEL(l)) {
+ jk_log(l, JK_LOG_DEBUG,
+ "Resetting the shared memory for child %d",
+ nchild);
+ }
+ }
+ jk_shmem.hdr->h.data.pos = 0;
+ jk_shmem.hdr->h.data.workers = 0;
+ }
+ JK_INIT_CS(&(jk_shmem.cs), rc);
+ if ((rc = do_shm_open_lock(jk_shmem.filename, attached, l))) {
+ if (!attached) {
+ munmap((void *)jk_shmem.hdr, jk_shmem.size);
+ close(jk_shmem.fd);
+#ifdef AS400_UTF8
+ wptr = (char *)malloc(strlen(jk_shmem.filename) + 1);
+ jk_ascii2ebcdic((char *)jk_shmem.filename, wptr);
+ unlink(wptr);
+ free(wptr);
+#else
+ unlink(jk_shmem.filename);
+#endif
+ }
+ 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;
+#ifdef AS400_UTF8
+ char *wptr;
+#endif
+
+ if (jk_shmem.hdr) {
+ --jk_shmem.hdr->h.data.childs;
+
+#ifdef JK_SHM_LOCK_REOPEN
+ if (jk_shmem.fd_lock >= 0) {
+ close(jk_shmem.fd_lock);
+ jk_shmem.fd_lock = -1;
+ }
+#endif
+ JK_DELETE_CS(&(jk_shmem.cs), rc);
+ if (jk_shmem.attached) {
+ int p = (int)getpid();
+ if (p == jk_shmem.attached) {
+ /* In case this is a forked child
+ * do not close the shared memory.
+ * It will be closed by the parent.
+ */
+ jk_shmem.size = 0;
+ jk_shmem.hdr = NULL;
+ jk_shmem.fd = -1;
+ return;
+ }
+ }
+ if (jk_shmem.fd >= 0) {
+ munmap((void *)jk_shmem.hdr, jk_shmem.size);
+ close(jk_shmem.fd);
+ }
+ if (jk_shmem.fd_lock >= 0)
+ close(jk_shmem.fd_lock);
+ if (jk_shmem.lockname) {
+#ifdef AS400_UTF8
+ wptr = (char *)malloc(strlen(jk_shmem.lockname) + 1);
+ jk_ascii2ebcdic((char *)jk_shmem.lockname, wptr);
+ unlink(wptr);
+ free(wptr);
+#else
+ unlink(jk_shmem.lockname);
+#endif
+ free(jk_shmem.lockname);
+ jk_shmem.lockname = NULL;
+ }
+ if (jk_shmem.filename) {
+#ifdef AS400_UTF8
+ wptr = (char *)malloc(strlen(jk_shmem.filename) + 1);
+ jk_ascii2ebcdic((char *)jk_shmem.filename, wptr);
+ unlink(wptr);
+ free(wptr);
+#else
+ unlink(jk_shmem.filename);
+#endif
+ free(jk_shmem.filename);
+ jk_shmem.filename = NULL;
+ }
+ }
+ jk_shmem.size = 0;
+ jk_shmem.hdr = NULL;
+ jk_shmem.fd = -1;
+ jk_shmem.fd_lock = -1;
+}
+
+
+#endif
+
+void *jk_shm_alloc(jk_pool_t *p, size_t size)
+{
+ void *rc = NULL;
+
+ if (jk_shmem.hdr) {
+ size = JK_SHM_ALIGN(size);
+ if ((jk_shmem.hdr->h.data.size - jk_shmem.hdr->h.data.pos) >= size) {
+ rc = &(jk_shmem.hdr->buf[jk_shmem.hdr->h.data.pos]);
+ jk_shmem.hdr->h.data.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->h.data.modified;
+ else
+ return jk_workers_modified_time;
+}
+
+void jk_shm_set_workers_time(time_t t)
+{
+ if (jk_shmem.hdr)
+ jk_shmem.hdr->h.data.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 defined (WIN32)
+ if (rc == JK_TRUE && jk_shm_hlock != NULL) {
+ DWORD rv = WaitForSingleObject(jk_shm_hlock, INFINITE);
+ if (rv == WAIT_OBJECT_0 || rv == WAIT_ABANDONED)
+ rc = JK_TRUE;
+ else
+ rc = JK_FALSE;
+ }
+#else
+ if (rc == JK_TRUE && jk_shmem.fd_lock != -1) {
+ JK_ENTER_LOCK(jk_shmem.fd_lock, rc);
+ }
+#endif
+ return rc;
+}
+
+int jk_shm_unlock()
+{
+ int rc;
+ JK_LEAVE_CS(&(jk_shmem.cs), rc);
+#if defined (WIN32)
+ if (rc == JK_TRUE && jk_shm_hlock != NULL) {
+ if (!ReleaseMutex(jk_shm_hlock))
+ rc = JK_FALSE;
+ }
+#else
+ if (rc == JK_TRUE && jk_shmem.fd_lock != -1) {
+ JK_LEAVE_LOCK(jk_shmem.fd_lock, rc);
+ }
+#endif
+ return rc;
+}
+
+jk_shm_ajp_worker_t *jk_shm_alloc_ajp_worker(jk_pool_t *p)
+{
+ jk_shm_ajp_worker_t *w = (jk_shm_ajp_worker_t *)jk_shm_alloc(p, JK_SHM_AJP_WORKER_SIZE);
+ if (w) {
+ memset(w, 0, JK_SHM_AJP_WORKER_SIZE);
+ if (jk_shmem.hdr) {
+ jk_shmem.hdr->h.data.workers++;
+ w->h.id = jk_shmem.hdr->h.data.workers;
+ w->h.type = JK_AJP13_WORKER_TYPE;
+ }
+ else
+ w->h.id = -1;
+ }
+ return w;
+}
+
+jk_shm_lb_sub_worker_t *jk_shm_alloc_lb_sub_worker(jk_pool_t *p)
+{
+ jk_shm_lb_sub_worker_t *w = (jk_shm_lb_sub_worker_t *)jk_shm_alloc(p, JK_SHM_LB_SUB_WORKER_SIZE);
+ if (w) {
+ memset(w, 0, JK_SHM_LB_SUB_WORKER_SIZE);
+ if (jk_shmem.hdr) {
+ jk_shmem.hdr->h.data.workers++;
+ w->h.id = jk_shmem.hdr->h.data.workers;
+ w->h.type = JK_LB_SUB_WORKER_TYPE;
+ }
+ else
+ w->h.id = -1;
+ }
+ return w;
+}
+
+jk_shm_lb_worker_t *jk_shm_alloc_lb_worker(jk_pool_t *p)
+{
+ jk_shm_lb_worker_t *w = (jk_shm_lb_worker_t *)jk_shm_alloc(p, JK_SHM_LB_WORKER_SIZE);
+ if (w) {
+ memset(w, 0, JK_SHM_LB_WORKER_SIZE);
+ if (jk_shmem.hdr) {
+ jk_shmem.hdr->h.data.workers++;
+ w->h.id = jk_shmem.hdr->h.data.workers;
+ w->h.type = JK_LB_WORKER_TYPE;
+ }
+ else
+ w->h.id = -1;
+ }
+ return w;
+}