/** * Creates a new process to be executed by one of the kernel pipelines. * The structure pointed by attr is defined in rtdal_process_attr. * * rtdal_process_new() configures the process parameters and loads it into the * pipeline. The process won't execute until a success call to rtdal_process_run() * is performed. * * The address pointed by arg will be passed to the process as a parameter. * * Notes: The shared library must conform with the rtdal_process_t requirements. * * @param attr Configures the process attributes * @param arg Argument to pass to the process each execution cycle * @return non-null value on success, zero on error */ r_proc_t rtdal_process_new(struct rtdal_process_attr *attr, void *arg) { hdebug("binary=%s, proc=%d, pos=%d, finish=0x%x, arg=0x%x\n",attr->binary_path,attr->pipeline_id, attr->exec_position,attr->finish_callback,arg); assert(context); RTDAL_ASSERT_PARAM_P(attr); RTDAL_ASSERT_PARAM_P(arg); pthread_mutex_lock(&context->mutex); int i=0; /* find empty space on process db */ for (i=0;i<MAX(rtdal_process);i++) { if (!context->processes[i].pid) break; } if (i == MAX(rtdal_process)) { RTDAL_SETERROR(RTDAL_ERROR_NOSPACE); goto out; } if (attr->process_group_id > MAX_PROCESS_GROUP_ID) { RTDAL_SETERROR(RTDAL_ERROR_NOSPACE); goto out; } if (attr->process_group_id < 0) { RTDAL_SETERROR(RTDAL_ERROR_INVAL); goto out; } pgroup_notified_failure[attr->process_group_id] = 0; memset(&context->processes[i],0,sizeof(rtdal_process_t)); context->processes[i].pid=i+1; hdebug("i=%d, pid=%d\n",context->processes[i].pid); memcpy(&context->processes[i].attributes, attr, sizeof(struct rtdal_process_attr)); context->processes[i].arg = arg; context->processes[i].finish_code = FINISH_OK; if (pipeline_add(&context->pipelines[attr->pipeline_id], &context->processes[i]) == -1) { goto out; } if (rtdal_process_launch(&context->processes[i])) { pipeline_remove(&context->pipelines[attr->pipeline_id], &context->processes[i]); goto out; } pthread_mutex_unlock(&context->mutex); return (r_proc_t) &context->processes[i]; out: pthread_mutex_unlock(&context->mutex); return NULL; }
inline static void pipeline_run_thread_run_module(pipeline_t *pipe, rtdal_process_t *proc, int idx) { hdebug("pipeid=%d, pid=%d, idx=%d, run=%d\n",pipe->id,proc->pid,idx,proc->runnable); if (proc->runnable) { pipe->running_process = proc; pipe->running_process_idx = idx; proc->is_running = 1; if (proc->run_point(proc->arg)) { aerror_msg("Error running module %d:%d\n", pipe->id,pipe->running_process_idx); pipeline_remove(pipe,proc); proc->is_running = 0; } proc->is_running = 0; } }
/** * Removes a process from the system, previously loaded using rtdal_process_new(). * rtdal_process_remove() removes the process from the allocated pipeline and * then unloads the program code from memory. After, if a finish_callback function * was provided in the process attributes during rtdal_process_new(), it is now * called. * @param obj Pointer to the rtdal_process_t object. * @return Zero on success, -1 on error. */ int rtdal_process_remove(r_proc_t process) { RTDAL_ASSERT_PARAM(process); rtdal_process_t *obj = (rtdal_process_t*) process; hdebug("pid=%d\n",obj->pid) if (pipeline_remove((pipeline_t*) obj->pipeline, obj)) { return -1; } dlclose(obj->dl_handle); snprintf(tmp,LSTR_LEN,"/tmp/am_%d.so",obj->pid); snprintf(tmp2,LSTR_LEN,"rm %s",tmp); if (system(tmp2) == -1) { aerror("Error removing file\n"); return -1; } obj->pid = 0; return 0; }