about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMagnus Auvinen <magnus.auvinen@gmail.com>2008-09-07 21:13:24 +0000
committerMagnus Auvinen <magnus.auvinen@gmail.com>2008-09-07 21:13:24 +0000
commit3b086d616a9090f714c90c7985f10c5dc4bd5733 (patch)
tree8137021d446260adfc5eacd753f9e42ab5281e7d
parent6a4e17ea8520e9eb3a88ce15a9e337679d631775 (diff)
downloadzcatch-3b086d616a9090f714c90c7985f10c5dc4bd5733.tar.gz
zcatch-3b086d616a9090f714c90c7985f10c5dc4bd5733.zip
fixed threaded jobs
-rw-r--r--src/engine/client/ec_client.c57
-rw-r--r--src/engine/client/ec_srvbrowse.c73
-rw-r--r--src/engine/e_engine.c101
-rw-r--r--src/engine/e_engine.h10
-rw-r--r--src/engine/e_if_client.h2
-rw-r--r--src/engine/e_jobs.c76
-rw-r--r--src/engine/e_jobs.h33
-rw-r--r--src/engine/e_protocol.h6
-rw-r--r--src/game/client/components/menus_browser.cpp7
9 files changed, 243 insertions, 122 deletions
diff --git a/src/engine/client/ec_client.c b/src/engine/client/ec_client.c
index a99f901d..3acd2723 100644
--- a/src/engine/client/ec_client.c
+++ b/src/engine/client/ec_client.c
@@ -1289,31 +1289,37 @@ static void client_update()
 	client_serverbrowse_update();
 }
 
-static int client_getversion()
+
+static void client_versionupdate()
 {
-	NETADDR addr;
-	NETCHUNK packet;
+	static int state = 0;
+	static HOSTLOOKUP version_serveraddr;
 	
-	mem_zero(&addr, sizeof(NETADDR));
-	mem_zero(&packet, sizeof(NETCHUNK));
-	
-	if(net_host_lookup(config.cl_version_server, &addr, NETTYPE_IPV4))
+	if(state == 0)
 	{
-		dbg_msg("client/version", "could not find the address of %s, skipping version fetch", config.cl_version_server);
-		return -1;
+		engine_hostlookup(&version_serveraddr, config.cl_version_server);
+		state++;
+	}
+	else if(state == 1)
+	{
+		if(jobs_status(&version_serveraddr.job) == JOBSTATUS_DONE)
+		{
+			NETCHUNK packet;
+			
+			mem_zero(&packet, sizeof(NETCHUNK));
+			
+			version_serveraddr.addr.port = VERSIONSRV_PORT;
+			
+			packet.client_id = -1;
+			packet.address = version_serveraddr.addr;
+			packet.data = VERSIONSRV_GETVERSION;
+			packet.data_size = sizeof(VERSIONSRV_GETVERSION);
+			packet.flags = NETSENDFLAG_CONNLESS;
+			
+			netclient_send(net, &packet);
+			state++;
+		}
 	}
-	
-	addr.port = VERSIONSRV_PORT;
-	
-	packet.client_id = -1;
-	packet.address = addr;
-	packet.data = VERSIONSRV_GETVERSION;
-	packet.data_size = sizeof(VERSIONSRV_GETVERSION);
-	packet.flags = NETSENDFLAG_CONNLESS;
-	
-	netclient_send(net, &packet);
-	
-	return 0;
 }
 
 extern int editor_update_and_render();
@@ -1336,7 +1342,7 @@ static void client_run()
 		return;
 
 	/* start refreshing addresses while we load */
-	mastersrv_refresh_addresses();
+	/* mastersrv_refresh_addresses(); */
 	
 	/* init the editor */
 	editor_init();
@@ -1363,9 +1369,6 @@ static void client_run()
 	config.cl_connect[0] = 0;
 	*/
 	
-	/* fetch latest client-version from versionsrv */
-	client_getversion();
-	
 	/* never start with the editor */
 	config.cl_editor = 0;
 		
@@ -1377,7 +1380,11 @@ static void client_run()
 		int64 frame_start_time = time_get();
 		frames++;
 		
+		
 		perf_start(&rootscope);
+
+		/* */
+		client_versionupdate();
 		
 		/* update input */
 		{
diff --git a/src/engine/client/ec_srvbrowse.c b/src/engine/client/ec_srvbrowse.c
index 98f60643..20a80e97 100644
--- a/src/engine/client/ec_srvbrowse.c
+++ b/src/engine/client/ec_srvbrowse.c
@@ -49,6 +49,8 @@ static SERVERENTRY *first_req_server = 0; /* request list */
 static SERVERENTRY *last_req_server = 0;
 static int num_requests = 0;
 
+static int need_refresh = 0;
+
 static int num_sorted_servers = 0;
 static int num_sorted_servers_capacity = 0;
 static int num_servers = 0;
@@ -489,30 +491,8 @@ void client_serverbrowse_refresh(int type)
 	}
 	else if(type == BROWSETYPE_INTERNET)
 	{
-		NETADDR addr;
-		NETCHUNK p;
-		int i;
-		
-		/*net_host_lookup(config.masterserver, MASTERSERVER_PORT, &master_server);*/
-
-		mem_zero(&p, sizeof(p));
-		p.client_id = -1;
-		p.flags = NETSENDFLAG_CONNLESS;
-		p.data_size = sizeof(SERVERBROWSE_GETLIST);
-		p.data = SERVERBROWSE_GETLIST;
-		
-		for(i = 0; i < MAX_MASTERSERVERS; i++)
-		{
-			addr = mastersrv_get(i);
-			if(!addr.ip[0] && !addr.ip[1] && !addr.ip[2] && !addr.ip[3])
-				continue;
-			
-			p.address = addr;
-			netclient_send(net, &p);
-		}
-
-		if(config.debug)
-			dbg_msg("client", "requesting server list");
+		need_refresh = 1;
+		mastersrv_refresh_addresses();
 	}
 	else if(type == BROWSETYPE_FAVORITES)
 	{
@@ -524,7 +504,7 @@ void client_serverbrowse_refresh(int type)
 
 static void client_serverbrowse_request(SERVERENTRY *entry)
 {
-	unsigned char buffer[sizeof(SERVERBROWSE_GETINFO)+1];
+	/*unsigned char buffer[sizeof(SERVERBROWSE_GETINFO)+1];*/
 	NETCHUNK p;
 
 	if(config.debug)
@@ -534,15 +514,15 @@ static void client_serverbrowse_request(SERVERENTRY *entry)
 			entry->addr.ip[3], entry->addr.port);
 	}
 	
-	mem_copy(buffer, SERVERBROWSE_GETINFO, sizeof(SERVERBROWSE_GETINFO));
-	buffer[sizeof(SERVERBROWSE_GETINFO)] = current_token;
+	/*mem_copy(buffer, SERVERBROWSE_GETINFO, sizeof(SERVERBROWSE_GETINFO));
+	buffer[sizeof(SERVERBROWSE_GETINFO)] = current_token;*/
 	
 	p.client_id = -1;
 	p.address = entry->addr;
 	p.flags = NETSENDFLAG_CONNLESS;
-	p.data_size = sizeof(buffer);
+	/*p.data_size = sizeof(buffer);
 	p.data = buffer;
-	netclient_send(net, &p);
+	netclient_send(net, &p);*/
 
 	/* send old requtest style aswell */	
 	p.data_size = sizeof(SERVERBROWSE_OLD_GETINFO);
@@ -559,6 +539,35 @@ void client_serverbrowse_update()
 	int count;
 	SERVERENTRY *entry, *next;
 	
+	/* do server list requests */
+	if(need_refresh && !mastersrv_refreshing())
+	{
+		NETADDR addr;
+		NETCHUNK p;
+		int i;
+		
+		need_refresh = 0;
+		
+		mem_zero(&p, sizeof(p));
+		p.client_id = -1;
+		p.flags = NETSENDFLAG_CONNLESS;
+		p.data_size = sizeof(SERVERBROWSE_GETLIST);
+		p.data = SERVERBROWSE_GETLIST;
+		
+		for(i = 0; i < MAX_MASTERSERVERS; i++)
+		{
+			addr = mastersrv_get(i);
+			if(!addr.ip[0] && !addr.ip[1] && !addr.ip[2] && !addr.ip[3])
+				continue;
+			
+			p.address = addr;
+			netclient_send(net, &p);
+		}
+
+		if(config.debug)
+			dbg_msg("client", "requesting server list");
+	}
+	
 	/* do timeouts */
 	entry = first_req_server;
 	while(1)
@@ -660,3 +669,9 @@ void client_serverbrowse_save()
 		engine_config_write_line(buffer);
 	}
 }
+
+
+int client_serverbrowse_refreshingmasters()
+{
+	return mastersrv_refreshing();
+}
diff --git a/src/engine/e_engine.c b/src/engine/e_engine.c
index 3c3c1d62..45eecfe3 100644
--- a/src/engine/e_engine.c
+++ b/src/engine/e_engine.c
@@ -13,6 +13,8 @@
 #include <engine/e_network.h>
 #include "e_linereader.h"
 
+static JOBPOOL hostlookuppool;
+
 static void con_dbg_dumpmem(void *result, void *user_data)
 {
 	mem_debug_dump();
@@ -63,6 +65,8 @@ void engine_init(const char *appname)
 	/* init console and add the console logger */
 	console_init();
 	dbg_logger(console_print);
+	
+	jobs_initpool(&hostlookuppool, 1);
 
 	MACRO_REGISTER_COMMAND("dbg_dumpmem", "", con_dbg_dumpmem, 0x0);
 	
@@ -224,65 +228,29 @@ void perf_dump(PERFORMACE_INFO *top)
 }
 
 /* master server functions */
-enum
-{
-	NUM_LOOKUP_THREADS=4,
-	
-	STATE_PROCESSED=0,
-	STATE_RESULT,
-	STATE_QUERYING
-};
-
 typedef struct
 {
 	char hostname[128];
 	NETADDR addr;
 	
-	/* these are used for lookups */
-	struct {
-		NETADDR addr;
-		int result;
-		void *thread;
-		volatile int state;
-	} lookup;
+	HOSTLOOKUP lookup;
 } MASTER_INFO;
 
-typedef struct
-{
-	int start;
-	int num;
-} THREAD_INFO;
-
 static MASTER_INFO master_servers[MAX_MASTERSERVERS] = {{{0}}};
-static THREAD_INFO thread_info[NUM_LOOKUP_THREADS];
-static int needs_update = 0;
-
-void lookup_thread(void *user)
-{
-	THREAD_INFO *info = (THREAD_INFO *)user;
-	int i;
-	
-	for(i = 0; i < info->num; i++)
-	{
-		int index = info->start+i;
-		master_servers[index].lookup.result = net_host_lookup(master_servers[index].hostname, &master_servers[index].lookup.addr, NETTYPE_IPV4);
-		master_servers[index].lookup.state = STATE_RESULT;
-	}
-}
+static int needs_update = -1;
 
 int mastersrv_refresh_addresses()
 {
 	int i;
-	dbg_msg("engine/mastersrv", "refreshing master server addresses");
 	
-	/* spawn threads that does the lookups */
-	for(i = 0; i < NUM_LOOKUP_THREADS; i++)	
-	{
-		thread_info[i].start = MAX_MASTERSERVERS/NUM_LOOKUP_THREADS * i;
-		thread_info[i].num = MAX_MASTERSERVERS/NUM_LOOKUP_THREADS;
-		master_servers[i].lookup.state = STATE_QUERYING;
-		master_servers[i].lookup.thread = thread_create(lookup_thread, &thread_info[i]);
-	}
+	if(needs_update != -1)
+		return 0;
+	
+	dbg_msg("engine/mastersrv", "refreshing master server addresses");
+
+	/* add lookup jobs */
+	for(i = 0; i < MAX_MASTERSERVERS; i++)	
+		engine_hostlookup(&master_servers[i].lookup, master_servers[i].hostname);
 	
 	needs_update = 1;
 	return 0;
@@ -293,37 +261,23 @@ void mastersrv_update()
 	int i;
 	
 	/* check if we need to update */
-	if(!needs_update)
+	if(needs_update != 1)
 		return;
 	needs_update = 0;
 	
 	for(i = 0; i < MAX_MASTERSERVERS; i++)
 	{
-		if(master_servers[i].lookup.state == STATE_RESULT)
+		if(jobs_status(&master_servers[i].lookup.job) != JOBSTATUS_DONE)
+			needs_update = 1;
+		else
 		{
-			/* we got a result from the lookup ready */
-			if(master_servers[i].lookup.result == 0)
-			{
-				master_servers[i].addr = master_servers[i].lookup.addr;
-				master_servers[i].addr.port = 8300;
-			}
-			master_servers[i].lookup.state = STATE_PROCESSED;
+			master_servers[i].addr = master_servers[i].lookup.addr;
+			master_servers[i].addr.port = 8300;
 		}
-
-		/* set the needs_update flag if we isn't done */		
-		if(master_servers[i].lookup.state != STATE_PROCESSED)
-			needs_update = 1;
 	}
 	
 	if(!needs_update)
 	{
-		/* make sure to destroy the threads */
-		for(i = 0; i < NUM_LOOKUP_THREADS; i++)
-		{
-			thread_destroy(master_servers[i].lookup.thread);
-			master_servers[i].lookup.thread = 0;
-		}
-			
 		dbg_msg("engine/mastersrv", "saving addresses");
 		mastersrv_save();
 	}
@@ -436,3 +390,18 @@ int mastersrv_save()
 	io_close(file);
 	return 0;
 }
+
+
+int hostlookup_thread(void *user)
+{
+	HOSTLOOKUP *lookup = (HOSTLOOKUP *)user;
+	net_host_lookup(lookup->hostname, &lookup->addr, NETTYPE_IPV4);
+	return 0;
+}
+
+void engine_hostlookup(HOSTLOOKUP *lookup, const char *hostname)
+{
+	str_copy(lookup->hostname, hostname, sizeof(lookup->hostname));
+	jobs_add(&hostlookuppool, &lookup->job, hostlookup_thread, lookup);
+}
+
diff --git a/src/engine/e_engine.h b/src/engine/e_engine.h
index 1c247588..dfe2f6f5 100644
--- a/src/engine/e_engine.h
+++ b/src/engine/e_engine.h
@@ -1,5 +1,7 @@
 /* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
 
+#include "e_jobs.h"
+
 const char *engine_savepath(const char *filename, char *buffer, int max);
 void engine_init(const char *appname);
 void engine_parse_arguments(int argc, char **argv);
@@ -10,6 +12,14 @@ void engine_config_write_stop();
 
 int engine_stress(float probability);
 
+typedef struct HOSTLOOKUP
+{
+	JOB job;
+	char hostname[128];
+	NETADDR addr;
+} HOSTLOOKUP;
+
+void engine_hostlookup(HOSTLOOKUP *lookup, const char *hostname);
 
 enum
 {
diff --git a/src/engine/e_if_client.h b/src/engine/e_if_client.h
index 6137145b..91ea09b2 100644
--- a/src/engine/e_if_client.h
+++ b/src/engine/e_if_client.h
@@ -535,4 +535,6 @@ enum
 
 void client_serverbrowse_set(NETADDR *addr, int type, int token, SERVER_INFO *info);
 
+
+int client_serverbrowse_refreshingmasters();
 #endif
diff --git a/src/engine/e_jobs.c b/src/engine/e_jobs.c
new file mode 100644
index 00000000..e87b395a
--- /dev/null
+++ b/src/engine/e_jobs.c
@@ -0,0 +1,76 @@
+/* copyright (c) 2007 magnus auvinen, see licence.txt for more info */
+#include <base/system.h>
+#include "e_jobs.h"
+
+void worker_thread(void *user)
+{
+	JOBPOOL *pool = (JOBPOOL *)user;
+	
+	while(1)
+	{
+		JOB *job = 0;
+		
+		/* fetch job from queue */
+		lock_wait(pool->lock);
+		if(pool->first_job)
+		{
+			job = pool->first_job;
+			pool->first_job = pool->first_job->next;
+			if(pool->first_job)
+				pool->first_job->prev = 0;
+			else
+				pool->last_job = 0;
+		}
+		lock_release(pool->lock);
+		
+		/* do the job if we have one */
+		if(job)
+		{
+			job->status = JOBSTATUS_RUNNING;
+			job->result = job->func(job->func_data);
+			job->status = JOBSTATUS_DONE;
+		}
+		else
+			thread_sleep(10);
+	}
+	
+}
+
+int jobs_initpool(JOBPOOL *pool, int num_threads)
+{
+	int i;
+	
+	/* empty the pool */
+	mem_zero(pool, sizeof(JOBPOOL));
+	pool->lock = lock_create();
+	
+	/* start threads */
+	for(i = 0; i < num_threads; i++)
+		thread_create(worker_thread, pool);
+	return 0;
+}
+
+int jobs_add(JOBPOOL *pool, JOB *job, JOBFUNC func, void *data)
+{
+	mem_zero(job, sizeof(JOB));
+	job->func = func;
+	job->func_data = data;
+	
+	lock_wait(pool->lock);
+	
+	/* add job to queue */
+	job->prev = pool->last_job;
+	if(pool->last_job)
+		pool->last_job->next = job;
+	pool->last_job = job;
+	if(!pool->first_job)
+		pool->first_job = job;
+	
+	lock_release(pool->lock);
+	return 0;
+}
+
+int jobs_status(JOB *job)
+{
+	return job->status;
+}
diff --git a/src/engine/e_jobs.h b/src/engine/e_jobs.h
new file mode 100644
index 00000000..2b04a1e4
--- /dev/null
+++ b/src/engine/e_jobs.h
@@ -0,0 +1,33 @@
+
+typedef int (*JOBFUNC)(void *data);
+
+typedef struct JOB
+{
+	struct JOBPOOL *pool;
+	struct JOB *prev;
+	struct JOB *next;
+	volatile int status;
+	volatile int result;
+	JOBFUNC func;
+	void *func_data;
+} JOB;
+
+typedef struct JOBPOOL
+{
+	LOCK lock;
+	JOB *first_job;
+	JOB *last_job;
+} JOBPOOL;
+
+enum
+{
+	JOBSTATUS_PENDING=0,
+	JOBSTATUS_RUNNING,
+	JOBSTATUS_DONE
+	/*JOBSTATUS_ABORTING,*/
+	/*JOBSTATUS_ABORTED,*/
+};
+
+int jobs_initpool(JOBPOOL *pool, int num_threads);
+int jobs_add(JOBPOOL *pool, JOB *job, JOBFUNC func, void *data);
+int jobs_status(JOB *job);
diff --git a/src/engine/e_protocol.h b/src/engine/e_protocol.h
index 93441fe7..033db43c 100644
--- a/src/engine/e_protocol.h
+++ b/src/engine/e_protocol.h
@@ -41,6 +41,9 @@ enum
 	NETMSG_SNAPSMALL,		/* */
 	NETMSG_RCON_AUTH_STATUS,/* result of the authentication */
 	NETMSG_RCON_LINE,		/* line that should be printed to the remote console */
+
+	NETMSG_AUTH_CHALLANGE,	/* */
+	NETMSG_AUTH_RESULT,		/* */
 	
 	/* sent by client */
 	NETMSG_READY,			/* */
@@ -49,6 +52,9 @@ enum
 	NETMSG_RCON_CMD,		/* */ 
 	NETMSG_RCON_AUTH,		/* */
 	NETMSG_REQUEST_MAP_DATA,/* */
+
+	NETMSG_AUTH_START,		/* */
+	NETMSG_AUTH_RESPONSE,	/* */
 	
 	/* sent by both */
 	NETMSG_PING,
diff --git a/src/game/client/components/menus_browser.cpp b/src/game/client/components/menus_browser.cpp
index 5656bc7e..a462b421 100644
--- a/src/game/client/components/menus_browser.cpp
+++ b/src/game/client/components/menus_browser.cpp
@@ -122,7 +122,7 @@ void MENUS::render_serverbrowser_serverlist(RECT view)
 	ui_vsplit_r(&view, 15, &view, &scroll);
 	
 	int num_servers = client_serverbrowse_sorted_num();
-	
+
 	int num = (int)(view.h/cols[0].rect.h);
 	static int scrollbar = 0;
 	static float scrollvalue = 0;
@@ -312,7 +312,10 @@ void MENUS::render_serverbrowser_serverlist(RECT view)
 	ui_draw_rect(&status, vec4(1,1,1,0.25f), CORNER_B, 5.0f);
 	ui_vmargin(&status, 50.0f, &status);
 	char buf[128];
-	str_format(buf, sizeof(buf), "%d of %d servers, %d players", client_serverbrowse_sorted_num(), client_serverbrowse_num(), num_players);
+	if(client_serverbrowse_refreshingmasters())
+		str_format(buf, sizeof(buf), "Refreshing master servers...");
+	else
+		str_format(buf, sizeof(buf), "%d of %d servers, %d players", client_serverbrowse_sorted_num(), client_serverbrowse_num(), num_players);
 	ui_do_label(&status, buf, 14.0f, -1);
 }