mirror of
https://github.com/ddnet/ddnet.git
synced 2024-11-10 10:08:18 +00:00
fixed threaded jobs
This commit is contained in:
parent
6a4e17ea85
commit
3b086d616a
|
@ -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 */
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
|
@ -488,13 +490,64 @@ void client_serverbrowse_refresh(int type)
|
|||
dbg_msg("client", "broadcasting for servers");
|
||||
}
|
||||
else if(type == BROWSETYPE_INTERNET)
|
||||
{
|
||||
need_refresh = 1;
|
||||
mastersrv_refresh_addresses();
|
||||
}
|
||||
else if(type == BROWSETYPE_FAVORITES)
|
||||
{
|
||||
int i;
|
||||
for(i = 0; i < num_favorite_servers; i++)
|
||||
client_serverbrowse_set(&favorite_servers[i], BROWSESET_FAV_ADD, -1, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static void client_serverbrowse_request(SERVERENTRY *entry)
|
||||
{
|
||||
/*unsigned char buffer[sizeof(SERVERBROWSE_GETINFO)+1];*/
|
||||
NETCHUNK p;
|
||||
|
||||
if(config.debug)
|
||||
{
|
||||
dbg_msg("client", "requesting server info from %d.%d.%d.%d:%d",
|
||||
entry->addr.ip[0], entry->addr.ip[1], entry->addr.ip[2],
|
||||
entry->addr.ip[3], entry->addr.port);
|
||||
}
|
||||
|
||||
/*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 = buffer;
|
||||
netclient_send(net, &p);*/
|
||||
|
||||
/* send old requtest style aswell */
|
||||
p.data_size = sizeof(SERVERBROWSE_OLD_GETINFO);
|
||||
p.data = SERVERBROWSE_OLD_GETINFO;
|
||||
netclient_send(net, &p);
|
||||
|
||||
entry->request_time = time_get();
|
||||
}
|
||||
|
||||
void client_serverbrowse_update()
|
||||
{
|
||||
int64 timeout = time_freq();
|
||||
int64 now = time_get();
|
||||
int count;
|
||||
SERVERENTRY *entry, *next;
|
||||
|
||||
/* do server list requests */
|
||||
if(need_refresh && !mastersrv_refreshing())
|
||||
{
|
||||
NETADDR addr;
|
||||
NETCHUNK p;
|
||||
int i;
|
||||
|
||||
/*net_host_lookup(config.masterserver, MASTERSERVER_PORT, &master_server);*/
|
||||
|
||||
need_refresh = 0;
|
||||
|
||||
mem_zero(&p, sizeof(p));
|
||||
p.client_id = -1;
|
||||
p.flags = NETSENDFLAG_CONNLESS;
|
||||
|
@ -514,50 +567,6 @@ void client_serverbrowse_refresh(int type)
|
|||
if(config.debug)
|
||||
dbg_msg("client", "requesting server list");
|
||||
}
|
||||
else if(type == BROWSETYPE_FAVORITES)
|
||||
{
|
||||
int i;
|
||||
for(i = 0; i < num_favorite_servers; i++)
|
||||
client_serverbrowse_set(&favorite_servers[i], BROWSESET_FAV_ADD, -1, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static void client_serverbrowse_request(SERVERENTRY *entry)
|
||||
{
|
||||
unsigned char buffer[sizeof(SERVERBROWSE_GETINFO)+1];
|
||||
NETCHUNK p;
|
||||
|
||||
if(config.debug)
|
||||
{
|
||||
dbg_msg("client", "requesting server info from %d.%d.%d.%d:%d",
|
||||
entry->addr.ip[0], entry->addr.ip[1], entry->addr.ip[2],
|
||||
entry->addr.ip[3], entry->addr.port);
|
||||
}
|
||||
|
||||
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 = buffer;
|
||||
netclient_send(net, &p);
|
||||
|
||||
/* send old requtest style aswell */
|
||||
p.data_size = sizeof(SERVERBROWSE_OLD_GETINFO);
|
||||
p.data = SERVERBROWSE_OLD_GETINFO;
|
||||
netclient_send(net, &p);
|
||||
|
||||
entry->request_time = time_get();
|
||||
}
|
||||
|
||||
void client_serverbrowse_update()
|
||||
{
|
||||
int64 timeout = time_freq();
|
||||
int64 now = time_get();
|
||||
int count;
|
||||
SERVERENTRY *entry, *next;
|
||||
|
||||
/* do timeouts */
|
||||
entry = first_req_server;
|
||||
|
@ -660,3 +669,9 @@ void client_serverbrowse_save()
|
|||
engine_config_write_line(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int client_serverbrowse_refreshingmasters()
|
||||
{
|
||||
return mastersrv_refreshing();
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/* set the needs_update flag if we isn't done */
|
||||
if(master_servers[i].lookup.state != STATE_PROCESSED)
|
||||
if(jobs_status(&master_servers[i].lookup.job) != JOBSTATUS_DONE)
|
||||
needs_update = 1;
|
||||
else
|
||||
{
|
||||
master_servers[i].addr = master_servers[i].lookup.addr;
|
||||
master_servers[i].addr.port = 8300;
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
|
@ -535,4 +535,6 @@ enum
|
|||
|
||||
void client_serverbrowse_set(NETADDR *addr, int type, int token, SERVER_INFO *info);
|
||||
|
||||
|
||||
int client_serverbrowse_refreshingmasters();
|
||||
#endif
|
||||
|
|
76
src/engine/e_jobs.c
Normal file
76
src/engine/e_jobs.c
Normal file
|
@ -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;
|
||||
}
|
33
src/engine/e_jobs.h
Normal file
33
src/engine/e_jobs.h
Normal file
|
@ -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);
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue