G_MODULE_EXPORT gboolean process_pf_message(gpointer data) { PostFunction *pf=NULL; Io_Message *message = (Io_Message *)data; extern gconstpointer *global_data; ENTER(); g_return_val_if_fail(message,FALSE); if (!message->status) { /* Message failed at some point, do NOT run post functions * in this case. */ dealloc_io_message(message); EXIT(); return FALSE; } if (message->command->post_functions != NULL) { gint len = message->command->post_functions->len; for (int i=0;i<len;i++) { pf = g_array_index(message->command->post_functions,PostFunction *, i); if (!pf) { MTXDBG(DISPATCHER,_("ERROR postfunction was NULL, continuing\n")); continue; } if (pf->name) { MTXDBG(DISPATCHER,_("dispatching post function %s\n"),pf->name); } if (pf->w_arg) { if (!pf->function_w_arg) MTXDBG(DISPATCHER,_("ERROR, couldn't find function with arg \"%s\"\n"),pf->name); else pf->function_w_arg(message); } else { if (!pf->function) MTXDBG(DISPATCHER,_("ERROR, couldn't find function \"%s\"\n"),pf->name); else pf->function(); } } }
/*! \brief thread_dispatcher() runs continuously as a thread listening to the io_data_queue and running handlers as messages come in. After they are done it passes the message back to the gui via the dispatch_queue for further gui handling (for things that can't run in a thread context) \param data is unused */ G_MODULE_EXPORT void *thread_dispatcher(gpointer data) { GThread * repair_thread = NULL; Serial_Params *serial_params = NULL; Io_Message *message = NULL; GAsyncQueue *io_data_queue = NULL; CmdLineArgs *args = NULL; void *(*network_repair_thread)(gpointer data) = NULL; void *(*serial_repair_thread)(gpointer data) = NULL; /* GTimer *clock;*/ ENTER(); io_data_queue = (GAsyncQueue *)DATA_GET(global_data,"io_data_queue"); serial_params = (Serial_Params *)DATA_GET(global_data,"serial_params"); get_symbol("serial_repair_thread",(void **)&serial_repair_thread); args = (CmdLineArgs *)DATA_GET(global_data,"args"); if (args->network_mode) get_symbol("network_repair_thread",(void **)&network_repair_thread); g_return_val_if_fail(args,NULL); g_return_val_if_fail(io_data_queue,NULL); g_return_val_if_fail(serial_params,NULL); g_async_queue_ref(io_data_queue); /* clock = g_timer_new();*/ /* Endless Loop, wait for message, processs and repeat... */ while (TRUE) { if (DATA_GET(global_data,"thread_dispatcher_exit")) { fast_exit: /* drain queue and exit thread */ while ((message = (Io_Message *)g_async_queue_try_pop(io_data_queue)) != NULL) dealloc_io_message(message); g_async_queue_unref(io_data_queue); EXIT(); g_thread_exit(0); } message = (Io_Message *)g_async_queue_timeout_pop(io_data_queue,1000000); if (!message) /* NULL message */ { MTXDBG(THREADS|IO_MSG,_("No message received...\n")); continue; } else MTXDBG(THREADS|IO_MSG,_("MESSAGE ARRIVED on IO queue...\n")); if ((!DATA_GET(global_data,"offline")) && (((!DATA_GET(global_data,"connected")) && (serial_params->open)) || (!(serial_params->open)))) { /*printf("somehow somethign went wrong, connected is %i, offline is %i, serial_params->open is %i\n",DATA_GET(global_data,"connected"),DATA_GET(global_data,"offline"),serial_params->open);*/ if (args->network_mode) { MTXDBG(THREADS,_("LINK DOWN, Initiating NETWORK repair thread!\n")); repair_thread = g_thread_new("Network Repair thread",network_repair_thread,NULL); } else { MTXDBG(THREADS,_("LINK DOWN, Initiating serial repair thread!\n")); repair_thread = g_thread_new("Serial Repair thread",serial_repair_thread,NULL); } g_thread_join(repair_thread); } if ((!serial_params->open) && (!DATA_GET(global_data,"offline"))) { MTXDBG(THREADS,_("LINK DOWN, Can't process requested command, aborting call\n")); thread_update_logbar("comm_view","warning",g_strdup("Disconnected Serial Link. Check Communications link/cable...\n"),FALSE,FALSE); thread_update_widget("titlebar",MTX_TITLE,g_strdup("Disconnected link, check Communications tab...")); message->status = FALSE; continue; } switch ((CmdType)message->command->type) { case FUNC_CALL: if (!message->command->function) MTXDBG(CRITICAL|THREADS,_("CRITICAL ERROR, function \"%s()\" is not found!!\n"),message->command->func_call_name); else { /*printf("Calling FUNC_CALL, function \"%s()\" \n",message->command->func_call_name);*/ message->status = message->command->function(message->command,message->command->func_call_arg); /* if (!result) message->command->defer_post_functions=TRUE; */ } break; case WRITE_CMD: /*g_timer_start(clock);*/ message->status = write_data(message); if (!message->status) DATA_SET(global_data,"connected",GINT_TO_POINTER(FALSE)); /*printf("Write command elapsed time %f\n",g_timer_elapsed(clock,NULL));*/ if (message) { if (message->command) { if (message->command->helper_function) { message->command->helper_function(message, message->command->helper_func_arg); } } } /*printf("Write command with post function time %f\n",g_timer_elapsed(clock,NULL));*/ break; case NULL_CMD: /*printf("null_cmd, just passing thru\n");*/ break; default: MTXDBG(THREADS|CRITICAL,_("Hit default case, this SHOULD NOT HAPPEN it's a bug, notify author! \n")); break; } /* If set to defer post functions, it means they were passed via a function fall, thus dealloc it here., Otherwise push up the queue to the postfunction dispatcher */ if (message->command->defer_post_functions) dealloc_io_message(message); else g_idle_add(process_pf_message,message); } EXIT(); return 0; }