costin 02/05/16 14:02:44 Modified: jk/native2/common jk_shm.c Log: Refactoring of jk_shm, using apr_mmap instead of apr_shm. Also added code for apache1.3 ( or if apr is not compiled ) - it's cut&paste from jserv, it work wherever jserv worked. While apr_shm may work on more platforms, I think it's better to use mmap since JDK1.4 will have this built-in and most platforms do have it. If mmap is not available - we just loose the ability to report statistics, and the eventual shm channel ( but jk will still work ). Revision Changes Path 1.16 +261 -153 jakarta-tomcat-connectors/jk/native2/common/jk_shm.c Index: jk_shm.c =================================================================== RCS file: /home/cvs/jakarta-tomcat-connectors/jk/native2/common/jk_shm.c,v retrieving revision 1.15 retrieving revision 1.16 diff -u -r1.15 -r1.16 --- jk_shm.c 15 May 2002 19:45:45 -0000 1.15 +++ jk_shm.c 16 May 2002 21:02:44 -0000 1.16 @@ -71,30 +71,24 @@ #include "jk_pool.h" #include "jk_shm.h" -#ifdef HAS_APR +/* global.h will include apr.h. If APR and mmap is compiled in, we'll use + it. If APR is not availalbe, we use mmap directly - the code worked fine + for jserv. +*/ +#if APR_HAS_MMAP + +#include "apr_mmap.h" +#include "apr_file_io.h" +#include "apr_file_info.h" +static apr_pool_t *globalShmPool; -#include "apr.h" -#include "apr_strings.h" -#include "apr_general.h" -#include "apr_portable.h" -#include "apr_lib.h" +#elif defined(HAVE_MMAP) && !defined(WIN32) -#define APR_WANT_STRFUNC -#include "apr_want.h" +#include <sys/mman.h> +#include <fcntl.h> -#if APR_HAVE_SYS_TYPES_H -#include <sys/types.h> #endif -#if APR_HAS_SHARED_MEMORY - -#include "apr_shm.h" -#include "apr_atomic.h" - -/* Inter-process synchronization - to create the slots */ -#include "apr_proc_mutex.h" - -static apr_pool_t *globalShmPool; #define SHM_SET_ATTRIBUTE 0 #define SHM_WRITE_SLOT 2 @@ -102,32 +96,265 @@ #define SHM_DETACH 4 #define SHM_RESET 5 #define SHM_DUMP 6 -#define SHM_DESTROY 7 +#ifdef APR_HAS_MMAP + static int jk2_shm_destroy(jk_env_t *env, jk_shm_t *shm) { - apr_shm_t *aprShm=(apr_shm_t *)shm->privateData; + apr_mmap_t *aprShm=(apr_mmap_t *)shm->privateData; - return apr_shm_destroy(aprShm); + if( aprShm==NULL ) + return JK_OK; + + return apr_mmap_delete(aprShm); } -static int JK_METHOD jk2_shm_detach(jk_env_t *env, jk_shm_t *shm) +static int jk2_shm_create(jk_env_t *env, jk_shm_t *shm) { - apr_shm_t *aprShm=(apr_shm_t *)shm->privateData; + int rc; + apr_file_t *file; + apr_finfo_t finfo; + apr_size_t size; + apr_mmap_t *aprMmap; + + /* We don't want to have to recreate the scoreboard after + * restarts, so we'll create a global pool and never clean it. + */ + if( globalShmPool==NULL ) { + /* Make sure apr is initialized */ + apr_initialize(); + rc = apr_pool_create(&globalShmPool, NULL); + if (rc != APR_SUCCESS || globalShmPool==NULL ) { + env->l->jkLog(env, env->l, JK_LOG_ERROR, + "Unable to create global pool for jk_shm\n"); + return rc; + } + } + + /* First make sure the file exists and is big enough + */ + rc=apr_file_open( &file, shm->fname, + APR_READ | APR_WRITE | APR_CREATE | APR_BINARY, + APR_OS_DEFAULT, globalShmPool); + if (rc!=JK_OK) { + char error[256]; + apr_strerror( rc, error, 256 ); + + env->l->jkLog(env, env->l, JK_LOG_ERROR, + "shm.create(): error opening file %s %d %s\n", + shm->fname, rc, error ); + shm->privateData=NULL; + return rc; + } + + rc=apr_file_info_get(&finfo, APR_FINFO_SIZE, file); + + if( shm->mbean->debug > 0 ) + env->l->jkLog(env, env->l, JK_LOG_INFO, + "shm.create(): file open %s %d %d\n", shm->fname, shm->size, finfo.size ); + + if( finfo.size < shm->size ) { + char bytes[1024]; + int toWrite=shm->size-finfo.size; + apr_off_t off=0; + + memset( bytes, 0, 1024 ); + apr_file_seek( file, APR_END, &off); - return apr_shm_detach(aprShm); + while( toWrite > 0 ) { + apr_size_t written; + rc=apr_file_write_full(file, bytes, 1024, &written); + if( rc!=APR_SUCCESS ) { + env->l->jkLog(env, env->l, JK_LOG_ERROR, + "shm.create(): Can't write %s %d %s\n", + shm->fname, errno, strerror( errno )); + return JK_ERR; + } + toWrite-=written; + } + + rc=apr_file_info_get(&finfo, APR_FINFO_SIZE, file); + } + + /* Now mmap it + */ + rc=apr_mmap_create( &aprMmap, file, (apr_off_t)0, + finfo.size, APR_MMAP_READ | APR_MMAP_WRITE, + globalShmPool ); + if( rc!=JK_OK ) { + char error[256]; + apr_strerror( rc, error, 256 ); + + env->l->jkLog(env, env->l, JK_LOG_ERROR, + "shm.create(): error attaching shm, will create %s %d %p %s\n", + shm->fname, rc, globalShmPool, error ); + shm->privateData=NULL; + return rc; + } + + shm->privateData=aprMmap; + apr_mmap_offset(& shm->image, aprMmap, (apr_off_t)0); + shm->head = (jk_shm_head_t *)shm->image; + + if( shm->image==NULL ) { + env->l->jkLog(env, env->l, JK_LOG_ERROR, + "shm.create(): No base memory %s\n", shm->fname); + return JK_ERR; + } + + return JK_OK; +} + +#elif defined(HAVE_MMAP) && !defined(WIN32) + +static int jk2_shm_destroy(jk_env_t *env, jk_shm_t *shm) +{ + caddr_t shmf=(caddr_t)shm->privateData; + + munmap(shmf, shm->size); + + return JK_OK; } -static int jk2_shm_attach(jk_env_t *env, jk_shm_t *shm) +static int jk2_shm_create(jk_env_t *env, jk_shm_t *shm) { - return apr_shm_attach((apr_shm_t **)&shm->privateData, shm->fname, globalShmPool ); + int rc; + struct stat filestat; + + int fd = open(shm->fname, O_RDWR|O_CREAT, 0777); + + if (fd == -1) { + env->l->jkLog(env, env->l, JK_LOG_ERROR, + "shm.create(): Can't open %s %d %s\n", + shm->fname, errno, strerror( errno )); + return JK_ERR; + } + + rc=stat( shm->fname, &filestat); + if ( rc == -1) { + env->l->jkLog(env, env->l, JK_LOG_ERROR, + "shm.create(): Can't stat %s %d %s\n", + shm->fname, errno, strerror( errno )); + return JK_ERR; + } + + if( shm->mbean->debug > 0 ) + env->l->jkLog(env, env->l, JK_LOG_INFO, + "shm.create(): file open %s %d %d\n", shm->fname, shm->size, filestat.st_size ); + + if (filestat.st_size < shm->size ) { + char bytes[1024]; + int toWrite=shm->size - filestat.st_size; + + memset( bytes, 0, 1024 ); + lseek(fd, 0, SEEK_END); + + while( toWrite > 0 ) { + int written; + written=write(fd, bytes, 1024); + if( written == -1 ) { + env->l->jkLog(env, env->l, JK_LOG_ERROR, + "shm.create(): Can't write %s %d %s\n", + shm->fname, errno, strerror( errno )); + return JK_ERR; + } + toWrite-=written; + } + + rc=stat( shm->fname, &filestat); + if ( rc == -1) { + env->l->jkLog(env, env->l, JK_LOG_ERROR, + "shm.create(): Can't stat2 %s %d %s\n", + shm->fname, errno, strerror( errno )); + return JK_ERR; + } + } + + shm->privateData = mmap(NULL, filestat.st_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + + if (shm->privateData == (caddr_t)-1 || + shm->privateData == NULL ) { + env->l->jkLog(env, env->l, JK_LOG_ERROR, + "shm.create(): Can't mmap %s %d %s\n", + shm->fname, errno, strerror( errno )); + + close(fd); + return JK_ERR; + } + + shm->image = (void *)shm->privateData; + shm->head = (jk_shm_head_t *)shm->image; + + close(fd); + + return JK_OK; +} + +#else + +static int jk2_shm_destroy(jk_env_t *env, jk_shm_t *shm) +{ + return JK_OK; +} + + +static int jk2_shm_create(jk_env_t *env, jk_shm_t *shm) +{ + int rc; + + return JK_ERR; +} + +#endif + + +/* Create or reinit an existing scoreboard. The MPM can control whether + * the scoreboard is shared across multiple processes or not + */ +static int JK_METHOD jk2_shm_init(struct jk_env *env, jk_shm_t *shm) { + int rv=JK_OK; + + shm->privateData=NULL; + + if( shm->fname==NULL ) { + env->l->jkLog(env, env->l, JK_LOG_ERROR, "shm.init(): No file\n"); + return JK_ERR; + } + + /* make sure it's an absolute pathname */ + /* fname = ap_server_root_relative(pconf, ap_scoreboard_fname); */ + + if( shm->size == 0 ) { + shm->size = shm->slotSize * shm->slotMaxCount; + } + + if( shm->size <= 0 ) { + env->l->jkLog(env, env->l, JK_LOG_ERROR, + "shm.create(): No size %s\n", shm->fname); + return JK_ERR; + } + + rv=jk2_shm_create( env, shm ); + + if( rv!=JK_OK ) { + env->l->jkLog(env, env->l, JK_LOG_ERROR, + "shm.create(): error mmapping %s\n", + shm->fname ); + return rv; + } + + if( shm->mbean->debug > 0 ) + env->l->jkLog(env, env->l, JK_LOG_INFO, + "shm.create(): shm created %p\n", shm->head ); + + return JK_OK; } /** Reset the scoreboard, in case it gets corrupted. * Will remove all slots and set the head in the original state. */ -static int jk2_shm_reset(jk_env_t *env, jk_shm_t *shm) +static int JK_METHOD jk2_shm_reset(jk_env_t *env, jk_shm_t *shm) { if( shm->head == NULL ) { return JK_ERR; @@ -137,10 +364,10 @@ shm->head->slotSize = shm->slotSize; shm->head->slotMaxCount = shm->slotMaxCount; shm->head->lastSlot = 1; - - env->l->jkLog(env, env->l, JK_LOG_INFO, - "shm.init() Initalized %s %p\n", - shm->fname, shm->image); + + if( shm->mbean->debug > 0 ) + env->l->jkLog(env, env->l, JK_LOG_INFO, "shm.init() Reset %s %p\n", + shm->fname, shm->image); return JK_OK; } @@ -184,122 +411,6 @@ } -/* Create or reinit an existing scoreboard. The MPM can control whether - * the scoreboard is shared across multiple processes or not - */ -static int JK_METHOD jk2_shm_init(struct jk_env *env, jk_shm_t *shm) { - apr_status_t rv=APR_SUCCESS; - jk_shm_head_t *head; - - if( shm->fname==NULL ) { - env->l->jkLog(env, env->l, JK_LOG_ERROR, "shm.init(): No file\n"); - return JK_ERR; - } - - if( shm->size == 0 ) { - shm->size = shm->slotSize * shm->slotMaxCount; - } - - /* We don't want to have to recreate the scoreboard after - * restarts, so we'll create a global pool and never clean it. - */ - apr_initialize(); - rv = apr_pool_create(&globalShmPool, NULL); - - if (rv != APR_SUCCESS) { - env->l->jkLog(env, env->l, JK_LOG_ERROR, - "Unable to create global pool for jk_shm\n"); - return rv; - } - - shm->privateData=NULL; - - rv=apr_shm_attach((apr_shm_t **)&shm->privateData, shm->fname, globalShmPool ); - if( rv ) { - char error[256]; - apr_strerror( rv, error, 256 ); - - env->l->jkLog(env, env->l, JK_LOG_ERROR, - "shm.create(): error attaching shm, will create %s %d %p %s\n", - shm->fname, rv, globalShmPool, error ); - shm->privateData=NULL; - } else { - env->l->jkLog(env, env->l, JK_LOG_INFO, - "shm.create(): attaching to existing shm %s\n", - shm->fname ); - /* Get the base address, initialize it */ - shm->image = apr_shm_baseaddr_get( (apr_shm_t *)shm->privateData); - shm->head = (jk_shm_head_t *)shm->image; - - if( shm->image==NULL ) { - env->l->jkLog(env, env->l, JK_LOG_ERROR, - "shm.create(): No base memory %s\n", shm->fname); - return JK_ERR; - } - return JK_OK; - } - - if( shm->size <= 0 ) { - env->l->jkLog(env, env->l, JK_LOG_ERROR, - "shm.create(): No size %s\n", shm->fname); - return JK_ERR; - } - /* make sure it's an absolute pathname */ - /* fname = ap_server_root_relative(pconf, ap_scoreboard_fname); */ - - /* The shared memory file must not exist before we create the - * segment. */ - rv = apr_file_remove(shm->fname, globalShmPool ); /* ignore errors */ - if (rv) { - char error[256]; - apr_strerror( rv, error, 256 ); - - env->l->jkLog(env, env->l, JK_LOG_ERROR, - "shm.create(): error removing shm %s %d %s\n", - shm->fname, rv, error ); - shm->privateData=NULL; - } else { - env->l->jkLog(env, env->l, JK_LOG_ERROR, - "shm.create(): file removed ok\n"); - } - - rv = apr_shm_create((apr_shm_t **)&shm->privateData,(apr_size_t)shm->size, - shm->fname, globalShmPool); - - if (rv!=JK_OK) { - char error[256]; - apr_strerror( rv, error, 256 ); - - env->l->jkLog(env, env->l, JK_LOG_ERROR, - "shm.create(): error creating shm %d %s %d %s\n", - shm->size, - shm->fname, rv, error ); - shm->privateData=NULL; - return rv; - } - - if( shm->privateData==NULL ) { - env->l->jkLog(env, env->l, JK_LOG_ERROR, - "Unable to create %s %d\n", shm->fname, rv); - return JK_ERR; - } - - /* Get the base address, initialize it */ - shm->image = apr_shm_baseaddr_get( (apr_shm_t *)shm->privateData); - shm->head = (jk_shm_head_t *)shm->image; - - if( shm->image==NULL ) { - env->l->jkLog(env, env->l, JK_LOG_ERROR, - "shm.create(): No memory allocated %s\n", - shm->fname); - return JK_ERR; - } - - jk2_shm_reset( env, shm ); - - return JK_OK; -} - /* pos starts with 1 ( 0 is the head ) */ jk_shm_slot_t * JK_METHOD jk2_shm_getSlot(struct jk_env *env, struct jk_shm *shm, int pos) @@ -462,6 +573,7 @@ wEnv->registerHandler( env, wEnv, "shm", "shmDispatch", JK_HANDLE_SHM_DISPATCH, jk2_shm_dispatch, NULL ); + return JK_OK; } int JK_METHOD jk2_shm_factory( jk_env_t *env ,jk_pool_t *pool, @@ -469,7 +581,6 @@ const char *type, const char *name) { jk_shm_t *shm; - jk_workerEnv_t *wEnv; shm=(jk_shm_t *)pool->calloc(env, pool, sizeof(jk_shm_t)); @@ -492,12 +603,9 @@ shm->getId=jk2_shm_getId; shm->init=jk2_shm_init; shm->reset=jk2_shm_reset; - shm->destroy=jk2_shm_detach; + shm->destroy=jk2_shm_destroy; shm->setWorkerEnv=jk2_shm_setWorkerEnv; return JK_OK; } - -#endif /* APR_HAS_SHARED_MEMORY */ -#endif /* HAS_APR */
-- To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]> For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>