コード例 #1
0
ファイル: timeout_handlers.c プロジェクト: seank/MegaTunix
/*!
 \brief signal_read_rtvars_thread() is thread which fires off the read msg
 to get a new set of realtiem variables.  It does so by queing messages to
 a thread which handles I/O.  This function will check the queue depth and 
 if the queue is backed up it will skip sending a request for data, as that 
 will only aggravate the queue roadblock.
 \returns 0 on signal to exit
 */
G_MODULE_EXPORT void * signal_read_rtvars_thread(gpointer data)
{
	static void (*signal_read_rtvars)(void);
	static gboolean (*setup_rtv)(void);
	static gboolean (*teardown_rtv)(void);
	Serial_Params *serial_params;
	GMutex * mutex = g_mutex_new();
	GTimeVal time;
	GAsyncQueue *io_data_queue = NULL;
	GAsyncQueue *pf_dispatch_queue = NULL;
	GCond *rtv_thread_cond = NULL;
	GMutex *rtv_thread_mutex = NULL;

	serial_params = DATA_GET(global_data,"serial_params");
	io_data_queue = DATA_GET(global_data,"io_data_queue");
	pf_dispatch_queue = DATA_GET(global_data,"pf_dispatch_queue");
	rtv_thread_cond = DATA_GET(global_data,"rtv_thread_cond");
	rtv_thread_mutex = DATA_GET(global_data,"rtv_thread_mutex");
	get_symbol("signal_read_rtvars",(void *)&signal_read_rtvars);
	get_symbol("setup_rtv",(void *)&setup_rtv);
	get_symbol("teardown_rtv",(void *)&teardown_rtv);

	g_return_val_if_fail(serial_params,NULL);
	g_return_val_if_fail(signal_read_rtvars,NULL);
	g_return_val_if_fail(io_data_queue,NULL);
	g_return_val_if_fail(pf_dispatch_queue,NULL);
	g_return_val_if_fail(rtv_thread_cond,NULL);
	g_return_val_if_fail(rtv_thread_mutex,NULL);

	if (setup_rtv)
		if (!setup_rtv())
			g_thread_exit(NULL);
	g_mutex_lock(mutex);
	g_async_queue_ref(io_data_queue);
	g_async_queue_ref(pf_dispatch_queue);
	g_mutex_lock(rtv_thread_mutex);
	while (TRUE)
	{
		dbg_func(IO_MSG|THREADS,g_strdup(__FILE__": signal_read_rtvars_thread()\n\tsending message to thread to read RT vars\n"));

		signal_read_rtvars();

		/* Auto-throttling if gui gets sluggish */
		while (( g_async_queue_length(io_data_queue) > 2) || 
				(g_async_queue_length(pf_dispatch_queue) > 3))
		{
			g_get_current_time(&time);
			g_time_val_add(&time,1000*g_async_queue_length(pf_dispatch_queue));
			if (g_cond_timed_wait(rtv_thread_cond,rtv_thread_mutex,&time))
				goto breakout;
		}
		g_get_current_time(&time);
		g_time_val_add(&time,serial_params->read_wait*1000);
		if (g_cond_timed_wait(rtv_thread_cond,rtv_thread_mutex,&time))
			goto breakout;
	}
breakout:
	g_mutex_unlock(rtv_thread_mutex);
	g_async_queue_unref(io_data_queue);
	g_async_queue_unref(pf_dispatch_queue);
	g_mutex_unlock(mutex);
	g_mutex_free(mutex);
	if (teardown_rtv)
		teardown_rtv();
	g_thread_exit(0);
	return NULL;
}
コード例 #2
0
ファイル: freeems_plugin.c プロジェクト: BMWPower/MegaTunix
/*!
  \brief Shuts down any plugin allocated resources (Serial IO/threads/queues,
  etc) and deallocates anything that was allocated with plugin_init(), as well
  as de-registering any enums specific to this plugin. This allows the plugin
  to be safely uninstalled
  */
G_MODULE_EXPORT void plugin_shutdown()
{
	GThread *thread = NULL;
	GCond *cond = NULL;
	GAsyncQueue *queue = NULL;
	GHashTable *hash = NULL;
	GMutex *mutex = NULL;
	gint id = 0;

	ENTER();
	teardown_rtv();
	freeems_serial_disable();

	thread = (GThread *)DATA_GET(global_data,"packet_handler_thread");
	if (thread)
	{
		DATA_SET(global_data,"packet_handler_thread_exit",GINT_TO_POINTER(TRUE));
		g_thread_join(thread);
		DATA_SET(global_data,"packet_handler_thread",NULL);
		DATA_SET(global_data,"packet_handler_thread_exit",NULL);
	}
	queue = (GAsyncQueue *)DATA_GET(global_data,"burn_queue");
	if (queue)
	{
		deregister_packet_queue(PAYLOAD_ID,queue,RESPONSE_BURN_BLOCK_FROM_RAM_TO_FLASH);
		g_async_queue_unref(queue);
		DATA_SET(global_data,"burn_queue",NULL);
		queue = NULL;
	}
	queue = (GAsyncQueue *)DATA_GET(global_data,"FLASH_write_queue");
	if (queue)
	{
		deregister_packet_queue(PAYLOAD_ID,queue,RESPONSE_REPLACE_BLOCK_IN_FLASH);
		g_async_queue_unref(queue);
		DATA_SET(global_data,"FLASH_write_queue",NULL);
		queue = NULL;
	}
	queue = (GAsyncQueue *)DATA_GET(global_data,"RAM_write_queue");
	if (queue)
	{
		deregister_packet_queue(PAYLOAD_ID,queue,RESPONSE_UPDATE_BLOCK_IN_RAM);
		g_async_queue_unref(queue);
		DATA_SET(global_data,"RAM_write_queue",NULL);
		queue = NULL;
	}
	queue = (GAsyncQueue *)DATA_GET(global_data,"packet_queue");
	if (queue)
	{
		g_async_queue_unref(queue);
		DATA_SET(global_data,"packet_queue",NULL);
		queue = NULL;
	}
	hash = (GHashTable *)DATA_GET(global_data,"payload_id_queue_hash");
	if (hash)
		g_hash_table_destroy(hash);
	hash = NULL;
	DATA_SET(global_data,"payload_id_queue_hash",NULL);

	hash = (GHashTable *)DATA_GET(global_data,"sequence_num_queue_hash");
	if (hash)
		g_hash_table_destroy(hash);
	hash = NULL;
	DATA_SET(global_data,"sequence_num_queue_hash",NULL);

	cond = (GCond *)DATA_GET(global_data,"packet_handler_cond");
	if (cond)
		g_cond_free(cond);
	cond = NULL;
	DATA_SET(global_data,"packet_handler_cond",NULL);
	cond = (GCond *)DATA_GET(global_data,"serial_reader_cond");
	if (cond)
		g_cond_free(cond);
	cond = NULL;
	DATA_SET(global_data,"serial_reader_cond",NULL);
	mutex = (GMutex *)DATA_GET(global_data,"queue_mutex");
	if (mutex)
		g_mutex_free(mutex);
	DATA_SET(global_data,"queue_mutex",NULL);
	mutex = (GMutex *)DATA_GET(global_data,"atomic_sequence_mutex");
	if (mutex)
		g_mutex_free(mutex);
	DATA_SET(global_data,"atomic_sequence_mutex",NULL);
	mutex = (GMutex *)DATA_GET(global_data,"rtv_subscriber_mutex");
	if (mutex)
		g_mutex_free(mutex);
	DATA_SET(global_data,"rtv_subscriber_mutex",NULL);

	deregister_common_enums();
	EXIT();
	return;
}