bool ltr_int_register_slave(int socket, message_t &msg) { ltr_int_log_message("Trying to register slave!\n"); pthread_mutex_lock(&send_mx); slaves.insert(std::pair<std::string, int>(msg.str, socket)); ltr_int_log_message("Slave with profile '%s' @socket %d registered!\n", msg.str, socket); pthread_mutex_unlock(&send_mx); //Make sure the new section is created if needed... ltr_axes_t tmp_axes; tmp_axes = NULL; ltr_int_init_axes(&tmp_axes, msg.str); ltr_int_close_axes(&tmp_axes); if(save_prefs) { ltr_int_log_message("Checking for changed prefs...\n"); if(ltr_int_need_saving()) { ltr_int_log_message("Master is about to save changed preferences.\n"); ltr_int_save_prefs(NULL); } } if(new_slave_hook != NULL) { new_slave_hook(msg.str); } return true; }
static void *ltr_int_slave_reader_thread(void *param) { ltr_int_log_message("Slave reader thread function entered!\n"); (void) param; int received_frames = 0; master_works = false; while(1){ if(!ltr_int_try_start_master(&master_uplink, &master_downlink)){ break; } ltr_int_log_message("Master Uplink %d, Downlink %d\n", master_uplink, master_downlink); int poll_errs = 0; struct pollfd downlink_poll= { .fd = master_downlink, .events = POLLIN, .revents = 0 }; while(1){ downlink_poll.events = POLLIN; int fds = poll(&downlink_poll, 1, 1000); if(fds < 0){ ++poll_errs; ltr_int_my_perror("poll"); if(poll_errs > 3){break;}else{continue;} }else if(fds == 0){ if(!parent_alive()){ //printf("Parent %lu died! (1)\n", (unsigned long)ppid); return NULL; } continue; } if(downlink_poll.revents & POLLHUP){ break; } //We have a new message if(ltr_int_process_message(master_downlink)){ ++received_frames; if(received_frames > 20){ master_works = true; } } if(!parent_alive()){ //printf("Parent %lu died! (2)\n", (unsigned long)ppid); return NULL; } } } return NULL; } static void ltr_int_slave_main_loop() { //Prepare to process client requests struct ltr_comm *com = mmm.data; ltr_cmd cmd = NOP_CMD; bool recenter = false; bool quit_flag = false; while(!quit_flag){ if((com->cmd != NOP_CMD) || com->recenter || com->notify){ ltr_int_lockSemaphore(mmm.sem); cmd = (ltr_cmd)com->cmd; com->cmd = NOP_CMD; recenter = com->recenter; notify = com->notify; com->recenter = false; ltr_int_unlockSemaphore(mmm.sem); } int res = 0; do{ switch(cmd){ case PAUSE_CMD: res = ltr_int_send_message(master_uplink, CMD_PAUSE, 0); break; case RUN_CMD: res = ltr_int_send_message(master_uplink, CMD_WAKEUP, 0); break; case STOP_CMD: quit_flag = true; break; case FRAMES_CMD: res = ltr_int_send_message(master_uplink, CMD_FRAMES, 0); break; default: break; } if(res < 0){ usleep(100000); } if(!parent_alive()){ //printf("Parent %lu died! (3)\n", (unsigned long)ppid); break; } }while((res < 0) && (!quit_flag)); cmd = NOP_CMD; if(recenter){ ltr_int_log_message("Slave sending master recenter request!\n"); if(ltr_int_send_message(master_uplink, CMD_RECENTER, 0) >= 0){ //clear request only on successfull transmission recenter = false; } } if(!parent_alive()){ //printf("Parent %lu died! (3)\n", (unsigned long)ppid); break; } usleep(100000); } } //main slave function bool ltr_int_slave(const char *c_profile, const char *c_com_file, const char *ppid_str, const char *close_pipe_str, const char *notify_pipe_str) { unsigned long tmp_ppid; profile_name = ltr_int_my_strdup(c_profile); sscanf(ppid_str, "%lu", &tmp_ppid); int tmp_pipe = -1; sscanf(close_pipe_str, "%d", &tmp_pipe); if(tmp_pipe > 0){ close(tmp_pipe); } sscanf(notify_pipe_str, "%d", ¬ify_pipe); if(notify_pipe > 0){ fcntl(notify_pipe, F_SETFL, fcntl(notify_pipe, F_GETFL) | O_NONBLOCK); } //printf("Going to monitor parent %lu!\n", tmp_ppid); ppid = (pid_t)tmp_ppid; if(!ltr_int_read_prefs(NULL, false)){ ltr_int_log_message("Couldn't load preferences!\n"); return false; } ltr_int_init_axes(&axes, profile_name); //Prepare client comm channel char *com_file = ltr_int_my_strdup(c_com_file); if(!ltr_int_mmap_file(com_file, sizeof(struct ltr_comm), &mmm)){ ltr_int_log_message("Couldn't mmap file!!!\n"); return false; } free(com_file); if(pthread_create(&reader_tid, NULL, ltr_int_slave_reader_thread, NULL) == 0){ ltr_int_slave_main_loop(); pthread_join(reader_tid, NULL); } close_master_comms(&master_uplink, &master_downlink); ltr_int_unmap_file(&mmm); //finish prefs ltr_int_close_axes(&axes); ltr_int_free_prefs(); free(profile_name); ltr_int_gui_lock_clean(); close(notify_pipe); return true; }