www.pudn.com > ccache.rar > shm.c


/******************************************************************** 
	created:	2008/01/24 
	filename: 	shm.c 
	author:		Lichuang 
                 
	purpose:     
*********************************************************************/ 
 
#include "shm.h" 
#include "node.h" 
#include "hash.h" 
#include "lock.h" 
#include "operator.h" 
 
#include  
#include  
#include  
#include  
#include  
 
static int countsize(int nodenum, int nodesize, int hashitemnum); 
 
ccache_t* create_shm(int nodenum, int datasize, int hashitemnum, int keysize, const char* mapfilename, int init) 
{ 
    int nodesize = sizeof(struct node_t) + sizeof(char) * (keysize + datasize); 
    int mapfilesize = countsize(nodenum, nodesize, hashitemnum); 
    int fd; 
 
    fd = open(mapfilename, O_RDWR); 
    if (0 > fd) 
    { 
        return NULL;  
    } 
 
    struct stat st; 
    if (0 != fstat(fd, &st)) 
    { 
        return NULL; 
    } 
 
    if (st.st_size != mapfilesize) 
    { 
        if (0 != unlink(mapfilename)) 
        { 
            return NULL; 
        } 
        close(fd); 
 
        fd = open(mapfilename, O_RDWR | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR); 
        if (0 > fd) 
        { 
            return NULL; 
        } 
 
        init = 1; 
    }         
 
    if (init) 
    { 
        if (0 > lseek(fd, mapfilesize - 1, SEEK_SET)) 
        { 
            return NULL; 
        } 
 
        if (0 > write(fd, " ", 1)) 
        { 
            return NULL; 
        } 
    } 
 
    ccache_t* cache = mmap(0, mapfilesize, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); 
    if (MAP_FAILED == cache) 
    { 
        close(fd); 
        return NULL; 
    } 
 
    close(fd); 
 
    if (init) 
    { 
        cache->mapfilesize = mapfilesize; 
        cache->hashitemnum = hashitemnum; 
        cache->nodenum = nodenum; 
        cache->usednodenum = 0; 
        cache->firstfreenode = 0; 
        cache->lrufirst = cache->lrulast = -1; 
 
        cache->nodesize = nodesize; 
        cache->keysize = keysize; 
        cache->datasize = datasize; 
        cache->hashitemtolsize = hashitemnum * sizeof(struct hashitem_t); 
 
        if (0 > initthreadmutex(&(cache->mutex))) 
        { 
            return NULL; 
        } 
        if (0 > inithashitem(cache)) 
        { 
            return NULL; 
        } 
 
        INIT_NODES(cache); 
    } 
 
    return cache;         
} 
 
int destroy_shm(ccache_t* cache) 
{ 
    return munmap((void*)cache, cache->mapfilesize); 
} 
 
int countsize(int nodenum, int nodesize, int hashitemnum) 
{ 
    return (sizeof(struct ccache_t) 
            + nodenum * nodesize 
            + hashitemnum * sizeof(struct hashitem_t)); 
}