/* * stats_open * * Opens the resources needed for a stats object. After this call returns * successfully, the stats object is ready for use. * * The resources allocated by stats_open must be freed by a corresponding * call to stats_close(). * * Returns: * S_OK - success * ERROR_INVALID_PARAMETERS - the stats object passed was not valid */ int stats_open(struct stats *stats) { int err; if (!stats || stats->magic != STATS_MAGIC || stats->data != NULL) return ERROR_INVALID_PARAMETERS; assert(!lock_is_open(&stats->lock)); assert(!shared_memory_is_open(&stats->shmem)); assert(stats->data == NULL); /* open the lock */ err = lock_open(&stats->lock); if (err == S_OK) { /* acquire the lock to make the process of getting and initializing the shared memory atomic */ lock_acquire(&stats->lock); /* open the shared memory */ err = shared_memory_open(&stats->shmem); if (err == S_OK) { assert(shared_memory_size(&stats->shmem) == sizeof(struct stats_data)); assert(shared_memory_ptr(&stats->shmem) != NULL); /* get the pointer to the shared memory and initialize it if this process created it */ stats->data = (struct stats_data *) shared_memory_ptr(&stats->shmem); if (shared_memory_was_created(&stats->shmem)) { stats_init_data(stats); } assert(stats->data->hdr.stats_magic == STATS_MAGIC); } lock_release(&stats->lock); } assert((err == S_OK && stats->data != NULL) || (err != S_OK && stats->data == NULL)); return err; }
IPC_handle IPC_openSharedMemory(const IPC_str *name) { DEBUG_PRINT("%s( %s )\n", __FUNCTION__, name ); int mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH; int oflags = O_RDWR; ipc_handle_t h = NULL; void *ipc_drv_handle = shared_memory_open(name, 0); if(!ipc_drv_handle) { goto do_exit; } h = allocate_ipc_object(name, IPC_typeSharedMem); if(!h) { goto do_unregister_shm; } h->ipc_user = ipc_drv_handle; h->ipc_descr.ipc_shm = shm_open(h->ipc_name, oflags, mode); if(h->ipc_descr.ipc_shm < 0) { goto do_free_ipc_object; } DEBUG_PRINT("%s(): open shared memory - %s\n", __FUNCTION__, name); return h; do_free_ipc_object: delete_ipc_object(h); do_unregister_shm: shared_memory_close(ipc_drv_handle); do_exit: return NULL; }
IPC_handle IPC_createSharedMemory(const IPC_str *name, int size) { DEBUG_PRINT("%s( %s, 0x%x )\n", __FUNCTION__, name, size ); int mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH; int oflags = O_RDWR | O_CREAT | O_EXCL; ipc_handle_t h = NULL; int res = -1; void *ipc_drv_handle = shared_memory_open(name, size); if(!ipc_drv_handle) { goto do_exit; } h = allocate_ipc_object(name, IPC_typeSharedMem); if(!h) { goto do_unregister_shm; return NULL; } h->ipc_user = ipc_drv_handle; h->ipc_descr.ipc_shm = shm_open(h->ipc_name, oflags, mode); if(h->ipc_descr.ipc_shm < 0) { if(errno != EEXIST) goto do_free_ipc_object; h->ipc_descr.ipc_shm = shm_open(h->ipc_name, O_RDWR, mode); if(h->ipc_descr.ipc_shm < 0) goto do_free_ipc_object; struct stat st_buf; res = fstat(h->ipc_descr.ipc_shm, &st_buf); if(res < 0) goto do_free_ipc_object; if(st_buf.st_size > 0) { DEBUG_PRINT("%s(): open shared memory - %s\n", __FUNCTION__, name ); goto do_return_ipc_object; } res = ftruncate(h->ipc_descr.ipc_shm, size); if(res < 0) goto do_free_ipc_object; DEBUG_PRINT("%s(): open and init shared memory - %s\n", __FUNCTION__, name ); goto do_return_ipc_object; } res = ftruncate(h->ipc_descr.ipc_shm, size); if(res < 0) goto do_free_ipc_object; DEBUG_PRINT("%s(): create shared memory - %s\n", __FUNCTION__, name); do_return_ipc_object: h->ipc_size = size; return h; do_free_ipc_object: delete_ipc_object(h); do_unregister_shm: shared_memory_close(ipc_drv_handle); do_exit: return NULL; }