in native/common/jk_shm.c [529:716]
static int do_shm_open(const char *fname, int attached,
int sz, jk_log_context_t *l)
{
int rc;
int fd;
void *base;
#ifdef AS400_UTF8
char *wptr;
#endif
JK_TRACE_ENTER(l);
if (!jk_shm_inited_cs) {
jk_shm_inited_cs = 1;
JK_INIT_CS(&jk_shmem.cs, rc);
}
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;
}
if (sz < 0) {
jk_log(l, JK_LOG_ERROR, "Invalid shared memory size (%d)", sz);
JK_TRACE_EXIT(l);
return EINVAL;
}
jk_shmem.size = JK_SHM_ALIGN(JK_SHM_SLOT_SIZE + 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, 0600);
free(wptr);
#else
fd = open(jk_shmem.filename, O_RDWR|O_CREAT|O_TRUNC, 0600);
#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;
jk_shmem.hdr->h.data.maintain_checking = 0;
jk_shmem.hdr->h.data.maintain_time = time(NULL);
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 {
jk_shmem.hdr->h.data.childs++;
jk_shmem.attached = (int)getpid();
if (JK_IS_DEBUG_LEVEL(l))
jk_log(l, JK_LOG_DEBUG,
"Attached shared memory %s [%d] size=%u workers=%u free=%u addr=%#lx",
jk_shm_name(),
jk_shmem.hdr->h.data.childs,
jk_shmem.size, jk_shmem.hdr->h.data.workers - 1,
jk_shmem.hdr->h.data.size - jk_shmem.hdr->h.data.pos,
jk_shmem.hdr);
#if 0
/*
* 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;
#endif
}
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;
}