#include "my_shmem.h"

struct MY_SHMEM {
    apr_shm_t  * shmem;
    const void * end;
          void * current;
};

MY_SHMEM * my_shmem_make( apr_pool_t *p, apr_size_t size )
{
     MY_SHMEM  * my_shm;
     apr_shm_t * shm;
    
     /* Anonymous shared memory, no need for a child process to attach */
     if( apr_shm_create( &shm, size + sizeof( *my_shm ), NULL, p ) != APR_SUCCESS )
	  return NULL;
    
     my_shm          = ( MY_SHMEM * ) apr_shm_baseaddr_get( shm );
     my_shm->current = my_shm + sizeof( *my_shm );
     my_shm->shmem   = shm;
     my_shm->end     = my_shm->current + size;
    
     return my_shm;
}

void * my_shmem_alloc( MY_SHMEM *shm, apr_size_t size )
{
     void *p;

     p = shm->current;
    
     if( size > ( shm->end - shm->current ) )
	  return NULL;
	
     shm->current += size;
    
     return p;
}

void * my_shmem_calloc( MY_SHMEM *shm, apr_size_t size )
{
     void *new = my_shmem_alloc( shm, size );

     if( new )
	  memset( new, 0, size );
    
     return new;
}

apr_size_t my_shmem_avail( MY_SHMEM *shm )
{
     return ( shm->end - shm->current );
}

void my_shmem_destroy( MY_SHMEM *shm )
{
     apr_shm_destroy( shm->shmem );
}
