示例#1
0
svn_stringbuf_t *
svn_stringbuf_create_ensure(apr_size_t blocksize, apr_pool_t *pool)
{
  void *mem;
  svn_stringbuf_t *new_string;

  /* apr_palloc will allocate multiples of 8.
   * Thus, we would waste some of that memory if we stuck to the
   * smaller size. Note that this is safe even if apr_palloc would
   * use some other aligment or none at all. */

  ++blocksize; /* + space for '\0' */
  blocksize = APR_ALIGN_DEFAULT(blocksize);

  /* Allocate memory for svn_string_t and data in one chunk. */
  mem = apr_palloc(pool, sizeof(*new_string) + blocksize);

  /* Initialize header and string */
  new_string = mem;

  new_string->data = (char*)mem + sizeof(*new_string);
  new_string->data[0] = '\0';
  new_string->len = 0;
  new_string->blocksize = blocksize;
  new_string->pool = pool;

  return new_string;
}
示例#2
0
void
svn_stringbuf_ensure(svn_stringbuf_t *str, apr_size_t minimum_size)
{
  /* Keep doubling capacity until have enough. */
  if (str->blocksize < minimum_size)
    {
      if (str->blocksize == 0)
        /* APR will increase odd allocation sizes to the next
         * multiple for 8, for instance. Take advantage of that
         * knowledge and allow for the extra size to be used. */
        str->blocksize = APR_ALIGN_DEFAULT(minimum_size);
      else
        while (str->blocksize < minimum_size)
          {
            /* str->blocksize is aligned;
             * doubling it should keep it aligned */
            apr_size_t prev_size = str->blocksize;
            str->blocksize *= 2;

            /* check for apr_size_t overflow */
            if (prev_size > str->blocksize)
              {
                str->blocksize = minimum_size;
                break;
              }
          }

      str->data = (char *) my__realloc(str->data,
                                       str->len + 1,
                                       /* We need to maintain (and thus copy)
                                          the trailing nul */
                                       str->blocksize,
                                       str->pool);
    }
}
示例#3
0
/* Allocate the space for a memory buffer from POOL.
 * Return a pointer to the new buffer in *DATA and its size in *SIZE.
 * The buffer size will be at least MINIMUM_SIZE.
 *
 * N.B.: The stringbuf creation functions use this, but since stringbufs
 *       always consume at least 1 byte for the NUL terminator, the
 *       resulting data pointers will never be NULL.
 */
static APR_INLINE void
membuf_create(void **data, apr_size_t *size,
              apr_size_t minimum_size, apr_pool_t *pool)
{
  /* apr_palloc will allocate multiples of 8.
   * Thus, we would waste some of that memory if we stuck to the
   * smaller size. Note that this is safe even if apr_palloc would
   * use some other aligment or none at all. */
  minimum_size = APR_ALIGN_DEFAULT(minimum_size);
  *data = (!minimum_size ? NULL : apr_palloc(pool, minimum_size));
  *size = minimum_size;
}
示例#4
0
文件: heap.c 项目: aidanhs/teeterl
apr_byte_t *heap_alloc(heap_t *hp, int size)
{
	apr_byte_t *mem;

	size = APR_ALIGN_DEFAULT(size);
	heap_secure_space(hp, size);
	mem = (apr_byte_t *)heap_htop(hp);
	heap_htop(hp) += size;

	hp->alloc_size += size;
	return mem;
}
apr_status_t upload_progress_cache_init(apr_pool_t *pool, ServerConfig *config)
{

#if APR_HAS_SHARED_MEMORY
    apr_status_t result;
    apr_size_t size;
    upload_progress_cache_t *cache;
    apr_rmm_off_t block;

    if (config->cache_file) {
        /* Remove any existing shm segment with this name. */
        apr_shm_remove(config->cache_file, config->pool);
    }

    size = APR_ALIGN_DEFAULT(config->cache_bytes);
    result = apr_shm_create(&config->cache_shm, size, config->cache_file, config->pool);
    if (result != APR_SUCCESS) {
        return result;
    }

    /* Determine the usable size of the shm segment. */
    size = apr_shm_size_get(config->cache_shm);

    /* This will create a rmm "handler" to get into the shared memory area */
    result = apr_rmm_init(&config->cache_rmm, NULL,
                          apr_shm_baseaddr_get(config->cache_shm), size,
                          config->pool);
    if (result != APR_SUCCESS) {
        return result;
    }

    apr_pool_cleanup_register(config->pool, config , upload_progress_cache_module_kill, apr_pool_cleanup_null);
    
    /* init cache object */
    CACHE_LOCK();
    block = apr_rmm_calloc(config->cache_rmm, sizeof(upload_progress_cache_t));
    cache = block ? (upload_progress_cache_t *)apr_rmm_addr_get(config->cache_rmm, block) : NULL;
    if(cache == NULL) {
      CACHE_UNLOCK();
      return 0;
    }
    cache->head = NULL;
    config->cache_offset = block;
    config->cache = cache;
    CACHE_UNLOCK();
    
#endif

    return APR_SUCCESS;
}
/* Ensure that BUF has enough space for VIEW_LEN bytes.  */
static APR_INLINE svn_error_t *
size_buffer(char **buf, apr_size_t *buf_size,
            apr_size_t view_len, apr_pool_t *pool)
{
  if (view_len > *buf_size)
    {
      *buf_size *= 2;
      if (*buf_size < view_len)
        *buf_size = view_len;
      SVN_ERR_ASSERT(APR_ALIGN_DEFAULT(*buf_size) >= *buf_size);
      *buf = apr_palloc(pool, *buf_size);
    }

  return SVN_NO_ERROR;
}
示例#7
0
文件: heap.c 项目: aidanhs/teeterl
term_t heap_binary0(heap_t *hp, int bit_size)
{
	apr_byte_t *data;
	binary_t *bin;
	int bin_size = APR_ALIGN_DEFAULT(sizeof(*bin));
	int data_size = BIN_BYTE_SIZE(bit_size);
	int gap = bin_size + data_size;
	bin = (binary_t *)heap_alloc(hp, gap);
	data = (apr_byte_t *)bin + bin_size;
	bin->bit_size = bit_size;
	bin->data = data;
	bin->parent = noval;
	bin->offset = 0;
	return tag_binary(bin);
}
示例#8
0
apr_status_t util_ldap_cache_init(apr_pool_t *pool, util_ldap_state_t *st)
{
#if APR_HAS_SHARED_MEMORY
    apr_status_t result;
    apr_size_t size;

    if (st->cache_bytes > 0) {
        if (st->cache_file) {
            /* Remove any existing shm segment with this name. */
            apr_shm_remove(st->cache_file, st->pool);
        }

        size = APR_ALIGN_DEFAULT(st->cache_bytes);

        result = apr_shm_create(&st->cache_shm, size, st->cache_file, st->pool);
        if (result != APR_SUCCESS) {
            return result;
        }

        /* Determine the usable size of the shm segment. */
        size = apr_shm_size_get(st->cache_shm);

        /* This will create a rmm "handler" to get into the shared memory area */
        result = apr_rmm_init(&st->cache_rmm, NULL,
                              apr_shm_baseaddr_get(st->cache_shm), size,
                              st->pool);
        if (result != APR_SUCCESS) {
            return result;
        }
    }

#endif

    apr_pool_cleanup_register(st->pool, st , util_ldap_cache_module_kill, apr_pool_cleanup_null);

    st->util_ldap_cache =
        util_ald_create_cache(st,
                              st->search_cache_size,
                              st->search_cache_ttl,
                              util_ldap_url_node_hash,
                              util_ldap_url_node_compare,
                              util_ldap_url_node_copy,
                              util_ldap_url_node_free,
                              util_ldap_url_node_display);
    return APR_SUCCESS;
}
示例#9
0
apr_status_t util_ldap_cache_init(apr_pool_t *pool, util_ldap_state_t *st)
{
#if APR_HAS_SHARED_MEMORY
    apr_status_t result;
    apr_size_t size;

    size = APR_ALIGN_DEFAULT(st->cache_bytes);

    result = apr_shm_create(&st->cache_shm, size, st->cache_file, st->pool);
    if (result == APR_EEXIST) {
        /*
         * The cache could have already been created (i.e. we may be a child process).  See
         * if we can attach to the existing shared memory
         */
        result = apr_shm_attach(&st->cache_shm, st->cache_file, st->pool);
    } 
    if (result != APR_SUCCESS) {
        return result;
    }

    /* Determine the usable size of the shm segment. */
    size = apr_shm_size_get(st->cache_shm);

    /* This will create a rmm "handler" to get into the shared memory area */
    result = apr_rmm_init(&st->cache_rmm, NULL, 
                          apr_shm_baseaddr_get(st->cache_shm), size, 
                          st->pool);
    if (result != APR_SUCCESS) {
        return result;
    }

#endif

    apr_pool_cleanup_register(st->pool, st , util_ldap_cache_module_kill, apr_pool_cleanup_null);

    st->util_ldap_cache =
        util_ald_create_cache(st,
                              util_ldap_url_node_hash,
                              util_ldap_url_node_compare,
                              util_ldap_url_node_copy,
                              util_ldap_url_node_free,
                              util_ldap_url_node_display);
    return APR_SUCCESS;
}
示例#10
0
APU_DECLARE_NONSTD(apr_bucket_alloc_t *) apr_bucket_alloc_create_ex(
                                             apr_allocator_t *allocator)
{
    apr_bucket_alloc_t *list;
    apr_memnode_t *block;

    block = apr_allocator_alloc(allocator, ALLOC_AMT);
    if (!block) {
        return NULL;
    }
    list = (apr_bucket_alloc_t *)block->first_avail;
    list->pool = NULL;
    list->allocator = allocator;
    list->freelist = NULL;
    list->blocks = block;
    block->first_avail += APR_ALIGN_DEFAULT(sizeof(*list));

    return list;
}
示例#11
0
文件: shm.c 项目: MiKTeX/miktex
APR_DECLARE(apr_status_t) apr_shm_attach(apr_shm_t **m,
                                         const char *filename,
                                         apr_pool_t *pool)
{
    if (filename == NULL) {
        /* It doesn't make sense to attach to a segment if you don't know
         * the filename. */
        return APR_EINVAL;
    }
    else {
#if APR_USE_SHMEM_MMAP_TMP || APR_USE_SHMEM_MMAP_SHM
        apr_shm_t *new_m;
        apr_status_t status;
        int tmpfd;
        apr_file_t *file;   /* file where metadata is stored */
        apr_size_t nbytes;

        new_m = apr_palloc(pool, sizeof(apr_shm_t));
        new_m->pool = pool;
        new_m->filename = apr_pstrdup(pool, filename);
#if APR_USE_SHMEM_MMAP_SHM
        const char *shm_name = make_shm_open_safe_name(filename, pool);

        /* FIXME: SysV uses 0600... should we? */
        tmpfd = shm_open(shm_name, O_RDWR, 0644);
        if (tmpfd == -1) {
            return errno;
        }

        status = apr_os_file_put(&file, &tmpfd,
                                 APR_READ | APR_WRITE,
                                 pool); 
        if (status != APR_SUCCESS) {
            return status;
        }

#elif APR_USE_SHMEM_MMAP_TMP
        status = apr_file_open(&file, filename, 
                               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;
        }
#else
        return APR_ENOTIMPL;
#endif

        nbytes = sizeof(new_m->realsize);
        status = apr_file_read(file, (void *)&(new_m->realsize),
                               &nbytes);
        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;
        }

        new_m->reqsize = new_m->realsize - sizeof(apr_size_t);

        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;
        }

        /* metadata isn't part of the usable segment */
        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_attach,
                                  apr_pool_cleanup_null);
        *m = new_m;
        return APR_SUCCESS;

#elif APR_USE_SHMEM_SHMGET
        apr_shm_t *new_m;
        apr_status_t status;
        apr_file_t *file;   /* file where metadata is stored */
        apr_size_t nbytes;

        new_m = apr_palloc(pool, sizeof(apr_shm_t));

        status = apr_file_open(&file, filename, 
                               APR_FOPEN_READ, APR_OS_DEFAULT, pool);
        if (status != APR_SUCCESS) {
            return status;
        }

        nbytes = sizeof(new_m->reqsize);
        status = apr_file_read(file, (void *)&(new_m->reqsize),
                               &nbytes);
        if (status != APR_SUCCESS) {
            return status;
        }
        status = apr_file_close(file);
        if (status != APR_SUCCESS) {
            return status;
        }

        new_m->filename = apr_pstrdup(pool, filename);
        new_m->pool = pool;
        new_m->shmkey = our_ftok(filename);
        if (new_m->shmkey == (key_t)-1) {
            return errno;
        }
        if ((new_m->shmid = shmget(new_m->shmkey, 0, SHM_R | SHM_W)) == -1) {
            return errno;
        }
        if ((new_m->base = shmat(new_m->shmid, NULL, 0)) == (void *)-1) {
            return errno;
        }
        new_m->usable = new_m->base;
        new_m->realsize = new_m->reqsize;

        apr_pool_cleanup_register(new_m->pool, new_m, shm_cleanup_attach,
                                  apr_pool_cleanup_null);
        *m = new_m;
        return APR_SUCCESS;

#else
        return APR_ENOTIMPL;
#endif
    }
}
示例#12
0
文件: shm.c 项目: MiKTeX/miktex
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;
#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));
        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 */
#elif APR_USE_SHMEM_SHMGET_ANON
        new_m = apr_palloc(pool, sizeof(apr_shm_t));
        new_m->pool = pool;
        new_m->reqsize = reqsize;
        new_m->realsize = reqsize;
        new_m->filename = NULL;
        new_m->shmkey = IPC_PRIVATE;
        if ((new_m->shmid = shmget(new_m->shmkey, 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;
#else
        /* 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 */
#endif
    }

    /* Name-based shared memory */
    else {
        new_m = apr_palloc(pool, sizeof(apr_shm_t));
        new_m->pool = pool;
        new_m->reqsize = reqsize;
        new_m->filename = apr_pstrdup(pool, filename);
#if APR_USE_SHMEM_MMAP_SHM
        const char *shm_name = make_shm_open_safe_name(filename, pool);
#endif
#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 && status != APR_ESPIPE) {
            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: SysV uses 0600... should we? */
        tmpfd = shm_open(shm_name, O_RDWR | O_CREAT | O_EXCL, 0644);
        if (tmpfd == -1) {
            return errno;
        }

        status = apr_os_file_put(&file, &tmpfd,
                                 APR_READ | APR_WRITE | APR_CREATE | APR_EXCL,
                                 pool); 
        if (status != APR_SUCCESS) {
            return status;
        }

        status = apr_file_trunc(file, new_m->realsize);
        if (status != APR_SUCCESS && status != APR_ESPIPE) {
            shm_unlink(shm_name); /* we're failing, remove the object */
            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_SHM */

        /* 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_SHMGET
        new_m->realsize = reqsize;

        /* FIXME: APR_OS_DEFAULT is too permissive, switch to 600 I think. */
        status = apr_file_open(&file, filename, 
                               APR_FOPEN_WRITE | APR_FOPEN_CREATE | APR_FOPEN_EXCL,
                               APR_OS_DEFAULT, pool);
        if (status != APR_SUCCESS) {
            return status;
        }

        /* ftok() (on solaris at least) requires that the file actually
         * exist before calling ftok(). */
        new_m->shmkey = our_ftok(filename);
        if (new_m->shmkey == (key_t)-1) {
            apr_file_close(file);
            return errno;
        }

        if ((new_m->shmid = shmget(new_m->shmkey, new_m->realsize,
                                   SHM_R | SHM_W | IPC_CREAT | IPC_EXCL)) < 0) {
            apr_file_close(file);
            return errno;
        }

        if ((new_m->base = shmat(new_m->shmid, NULL, 0)) == (void *)-1) {
            apr_file_close(file);
            return errno;
        }
        new_m->usable = new_m->base;

        if (shmctl(new_m->shmid, IPC_STAT, &shmbuf) == -1) {
            apr_file_close(file);
            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) {
            apr_file_close(file);
            return errno;
        }

        nbytes = sizeof(reqsize);
        status = apr_file_write(file, (const void *)&reqsize,
                                &nbytes);
        if (status != APR_SUCCESS) {
            apr_file_close(file);
            return status;
        }
        status = apr_file_close(file);
        if (status != APR_SUCCESS) {
            return status;
        }

        apr_pool_cleanup_register(new_m->pool, new_m, shm_cleanup_owner,
                                  apr_pool_cleanup_null);
        *m = new_m; 
        return APR_SUCCESS;

#else
        return APR_ENOTIMPL;
#endif
    }
}
示例#13
0
static apr_status_t test_rmm(apr_pool_t *parpool)
{
    apr_status_t rv;
    apr_pool_t *pool;
    apr_shm_t *shm;
    apr_rmm_t *rmm;
    apr_size_t size, fragsize;
    apr_rmm_off_t *off;
    int i;
    void *entity;

    rv = apr_pool_create(&pool, parpool);
    if (rv != APR_SUCCESS) {
        fprintf(stderr, "Error creating child pool\n");
        return rv;
    }

    /* We're going to want 10 blocks of data from our target rmm. */
    size = SHARED_SIZE + apr_rmm_overhead_get(FRAG_COUNT + 1);
    printf("Creating anonymous shared memory (%"
           APR_SIZE_T_FMT " bytes).....", size); 
    rv = apr_shm_create(&shm, size, NULL, pool);
    if (rv != APR_SUCCESS) { 
        fprintf(stderr, "Error allocating shared memory block\n");
        return rv;
    }
    fprintf(stdout, "OK\n");

    printf("Creating rmm segment.............................");
    rv = apr_rmm_init(&rmm, NULL, apr_shm_baseaddr_get(shm), size,
                      pool);

    if (rv != APR_SUCCESS) {
        fprintf(stderr, "Error allocating rmm..............\n");
        return rv;
    }
    fprintf(stdout, "OK\n");

    fragsize = SHARED_SIZE / FRAG_COUNT;
    printf("Creating each fragment of size %" APR_SIZE_T_FMT "................",
           fragsize);
    off = apr_palloc(pool, FRAG_COUNT * sizeof(apr_rmm_off_t));
    for (i = 0; i < FRAG_COUNT; i++) {
        off[i] = apr_rmm_malloc(rmm, fragsize);
    } 
    fprintf(stdout, "OK\n");
    
    printf("Checking for out of memory allocation............");
    if (apr_rmm_malloc(rmm, FRAG_SIZE * FRAG_COUNT) == 0) {
        fprintf(stdout, "OK\n");
    }
    else {
        return APR_EGENERAL;  
    }

    printf("Checking each fragment for address alignment.....");
    for (i = 0; i < FRAG_COUNT; i++) {
        char *c = apr_rmm_addr_get(rmm, off[i]);
        apr_size_t sc = (apr_size_t)c;

        if (off[i] == 0) {
            printf("allocation failed for offset %d\n", i);
            return APR_ENOMEM;
        }

        if (sc & 7) {
            printf("Bad alignment for fragment %d; %p not %p!\n",
                   i, c, (void *)APR_ALIGN_DEFAULT((apr_size_t)c));
            return APR_EGENERAL;
        }
    }
    fprintf(stdout, "OK\n");   
    
    printf("Setting each fragment to a unique value..........");
    for (i = 0; i < FRAG_COUNT; i++) {
        int j;
        char **c = apr_rmm_addr_get(rmm, off[i]);
        for (j = 0; j < FRAG_SIZE; j++, c++) {
            *c = apr_itoa(pool, i + j);
        }
    } 
    fprintf(stdout, "OK\n");

    printf("Checking each fragment for its unique value......");
    for (i = 0; i < FRAG_COUNT; i++) {
        int j;
        char **c = apr_rmm_addr_get(rmm, off[i]);
        for (j = 0; j < FRAG_SIZE; j++, c++) {
            char *d = apr_itoa(pool, i + j);
            if (strcmp(*c, d) != 0) {
                return APR_EGENERAL;
            }
        }
    } 
    fprintf(stdout, "OK\n");

    printf("Freeing each fragment............................");
    for (i = 0; i < FRAG_COUNT; i++) {
        rv = apr_rmm_free(rmm, off[i]);
        if (rv != APR_SUCCESS) {
            return rv;
        }
    } 
    fprintf(stdout, "OK\n");

    printf("Creating one large segment.......................");
    off[0] = apr_rmm_calloc(rmm, SHARED_SIZE);
    fprintf(stdout, "OK\n");

    printf("Setting large segment............................");
    for (i = 0; i < FRAG_COUNT * FRAG_SIZE; i++) {
        char **c = apr_rmm_addr_get(rmm, off[0]);
        c[i] = apr_itoa(pool, i);
    }
    fprintf(stdout, "OK\n");

    printf("Freeing large segment............................");
    apr_rmm_free(rmm, off[0]);
    fprintf(stdout, "OK\n");

    printf("Creating each fragment of size %" APR_SIZE_T_FMT " (again)........",
           fragsize);
    for (i = 0; i < FRAG_COUNT; i++) {
        off[i] = apr_rmm_malloc(rmm, fragsize);
    } 
    fprintf(stdout, "OK\n");

    printf("Freeing each fragment backwards..................");
    for (i = FRAG_COUNT - 1; i >= 0; i--) {
        rv = apr_rmm_free(rmm, off[i]);
        if (rv != APR_SUCCESS) {
            return rv;
        }
    } 
    fprintf(stdout, "OK\n");

    printf("Creating one large segment (again)...............");
    off[0] = apr_rmm_calloc(rmm, SHARED_SIZE);
    fprintf(stdout, "OK\n");

    printf("Freeing large segment............................");
    apr_rmm_free(rmm, off[0]);
    fprintf(stdout, "OK\n");

    printf("Checking realloc.................................");
    off[0] = apr_rmm_calloc(rmm, SHARED_SIZE - 100);
    off[1] = apr_rmm_calloc(rmm, 100);
    if (off[0] == 0 || off[1] == 0) {
        printf("FAILED\n");
        return APR_EINVAL;
    }
    entity = apr_rmm_addr_get(rmm, off[1]);
    rv = apr_rmm_free(rmm, off[0]);
    if (rv != APR_SUCCESS) {
        printf("FAILED\n");
        return rv;
    }

    {
        unsigned char *c = entity;

        /* Fill in the region; the first half with zereos, which will
         * likely catch the apr_rmm_realloc offset calculation bug by
         * making it think the old region was zero length. */
        for (i = 0; i < 100; i++) {
            c[i] = (i < 50) ? 0 : i;
        }
    }

    /* now we can realloc off[1] and get many more bytes */
    off[0] = apr_rmm_realloc(rmm, entity, SHARED_SIZE - 100);
    if (off[0] == 0) {
        printf("FAILED\n");
        return APR_EINVAL;
    }

    {
        unsigned char *c = apr_rmm_addr_get(rmm, off[0]);

        /* fill in the region */
        for (i = 0; i < 100; i++) {
            if (c[i] != (i < 50 ? 0 : i)) {
                printf("FAILED at offset %d: %hx\n", i, c[i]);
                return APR_EGENERAL;
            }
        }
    }

    fprintf(stdout, "OK\n");

    printf("Destroying rmm segment...........................");
    rv = apr_rmm_destroy(rmm);
    if (rv != APR_SUCCESS) {
        printf("FAILED\n");
        return rv;
    }
    printf("OK\n");

    printf("Destroying shared memory segment.................");
    rv = apr_shm_destroy(shm);
    if (rv != APR_SUCCESS) {
        printf("FAILED\n");
        return rv;
    }
    printf("OK\n");

    apr_pool_destroy(pool);

    return APR_SUCCESS;
}
示例#14
0
文件: heap.c 项目: aidanhs/teeterl
void heap_anticipate_need(heap_t *hp, int size)
{
	size = APR_ALIGN_DEFAULT(size);
	heap_secure_space(hp, size);
}