Example #1
0
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();
			}

		}
	}
Example #2
0
/*!
  \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;
}