static void cleanup_actions(void) { int retval; if (global_data) { if (global_data->rtapi_app_pid > 0) { kill(global_data->rtapi_app_pid, SIGTERM); syslog_async(LOG_INFO,"sent SIGTERM to rtapi (pid %d)\n", global_data->rtapi_app_pid); } // in case some process catches a leftover shm segment global_data->magic = GLOBAL_EXITED; global_data->rtapi_msgd_pid = 0; if (rtapi_msg_buffer.header != NULL) rtapi_msg_buffer.header->refcount--; retval = shm_common_detach(sizeof(global_data_t), global_data); if (retval < 0) { syslog_async(LOG_ERR,"shm_common_detach(global) failed: %s\n", strerror(-retval)); } else { shm_common_unlink(OS_KEY(GLOBAL_KEY, rtapi_instance)); syslog_async(LOG_DEBUG,"normal shutdown - global segment detached"); } global_data = NULL; } }
int ulapi_exit(int instance) { rtapi_print_msg(RTAPI_MSG_DBG, "ULAPI:%d %s exit\n", instance, GIT_VERSION); if (rtapi_switch->thread_flavor_flags & FLAVOR_RTAPI_DATA_IN_SHM) { // detach RTAPI segment int retval = shm_common_detach(sizeof(rtapi_data_t), rtapi_data); if (retval) { rtapi_print_msg(RTAPI_MSG_ERR, "ULAPI:%d ERROR: shm_common_detach(rtapi_data)" " failed: %s\n", rtapi_instance, strerror(-retval)); } rtapi_data = NULL; } return 0; }
int _rtapi_shmem_delete_inst(int handle, int instance, int module_id) { shmem_data *shmem; int retval = 0; if(handle < 1 || handle >= RTAPI_MAX_SHMEMS) return -EINVAL; rtapi_mutex_get(&(rtapi_data->mutex)); shmem = &shmem_array[handle]; /* validate shmem handle */ if (shmem->magic != SHMEM_MAGIC) { rtapi_mutex_give(&(rtapi_data->mutex)); return -EINVAL; } shmem->count --; if(shmem->count) { rtapi_mutex_give(&(rtapi_data->mutex)); rtapi_print_msg(RTAPI_MSG_DBG, "rtapi_shmem_delete: handle=%d module=%d key=0x%x: " "%d remaining users\n", handle, module_id, shmem->key, shmem->count); return 0; } retval = shm_common_detach(shmem->size, shmem->mem); if (retval < 0) { rtapi_print_msg(RTAPI_MSG_ERR, "RTAPI:%d ERROR: munmap(0x%8.8x) failed: %s\n", instance, shmem->key, strerror(-retval)); } // XXX: probably shmem->mem should be set to NULL here to avoid // references to already unmapped segments (and find them early) /* free the shmem structure */ shmem->magic = 0; rtapi_mutex_give(&(rtapi_data->mutex)); return retval; }
int _rtapi_shmem_delete_inst(int shmem_id, int instance, int module_id) { shmem_data *shmem; int manage_lock, retval; #ifdef RTAPI struct shm_status sm; #endif /* validate shmem ID */ if ((shmem_id < 1) || (shmem_id > RTAPI_MAX_SHMEMS)) { return -EINVAL; } /* point to the shmem's data */ shmem = &(shmem_array[shmem_id]); /* is the block valid? */ if (shmem->key == 0) { return -EINVAL; } /* validate module_id */ if ((module_id < 1) || (module_id > RTAPI_MAX_MODULES)) { return -EINVAL; } if (module_array[module_id].state != MODULE_STATE) { return -EINVAL; } /* is this module using the block? */ if (rtapi_test_bit(module_id, shmem->bitmap) == 0) { return -EINVAL; } /* check if we need to manage the mutex */ manage_lock = (shmem->magic != SHMEM_MAGIC_DEL_LOCKED); /* if no magic delete lock held is set, get the mutex */ if (manage_lock) rtapi_mutex_get(&(rtapi_data->mutex)); /* OK, we're no longer using it */ rtapi_clear_bit(module_id, shmem->bitmap); #ifdef ULAPI shmem->ulusers--; if ((shmem->ulusers == 0) && (shmem->rtusers == 0)) { // shmdrv can detach unused shared memory from userland too // this will munmap() the segment causing a drop in uattach refcount // and eventual free by garbage collect in shmdrv retval = shm_common_detach(shmem->size, shmem_addr_array[shmem_id]); if (retval) { rtapi_print_msg(RTAPI_MSG_ERR, "ULAPI:%d ERROR: shm_common_detach(%02d) failed: %s\n", rtapi_instance, shmem_id, strerror(-retval)); } } /* unmap the block */ shmem_addr_array[shmem_id] = NULL; #else /* RTAPI */ shmem->rtusers--; #endif /* RTAPI */ /* is somebody else still using the block? */ if ((shmem->ulusers > 0) || (shmem->rtusers > 0)) { /* yes, we're done for now */ rtapi_print_msg(RTAPI_MSG_DBG, "RTAPI: shmem %02d closed by module %02d\n", shmem_id, module_id); if (manage_lock) rtapi_mutex_give(&(rtapi_data->mutex)); return 0; } #ifdef RTAPI /* no other realtime users, free the shared memory from kernel space */ shmem_addr_array[shmem_id] = NULL; shmem->rtusers = 0; /* are any user processes using the block? */ if (shmem->ulusers > 0) { /* yes, we're done for now */ rtapi_print_msg(RTAPI_MSG_DBG, "RTAPI: shmem %02d unmapped by module %02d\n", shmem_id, module_id); if (manage_lock) rtapi_mutex_give(&(rtapi_data->mutex)); return 0; } /* no other users at all, this ID is now free */ sm.key = shmem->key; sm.size = shmem->size; sm.flags = 0; if ((retval = shmdrv_detach(&sm)) < 0) { rtapi_print_msg(RTAPI_MSG_ERR, "RTAPI:%d ERROR: shmdrv_detach(%x,%d) fail: %d\n", rtapi_instance, sm.key, sm.size, retval); } #endif /* RTAPI */ /* update the data array and usage count */ shmem->key = 0; shmem->size = 0; rtapi_data->shmem_count--; /* release the lock if needed, print a debug message and return */ if (manage_lock) rtapi_mutex_give(&(rtapi_data->mutex)); rtapi_print_msg(RTAPI_MSG_DBG, "RTAPI: shmem %02d freed by module %02d\n", shmem_id, module_id); return 0; }