mirror of
git://xwords.git.sourceforge.net/gitroot/xwords/xwords
synced 2025-02-06 20:45:54 +01:00
use a single thread and a protected queue
I don't want race conditions between threads talking to the server.
This commit is contained in:
parent
6787fe1406
commit
c3887b9c77
1 changed files with 207 additions and 137 deletions
|
@ -36,6 +36,9 @@ typedef struct _RelayConStorage {
|
||||||
pthread_t mainThread;
|
pthread_t mainThread;
|
||||||
guint moveCheckerID;
|
guint moveCheckerID;
|
||||||
XP_U16 nextMoveCheckSecs;
|
XP_U16 nextMoveCheckSecs;
|
||||||
|
pthread_cond_t relayCondVar;
|
||||||
|
pthread_mutex_t relayMutex;
|
||||||
|
GSList* relayTaskList;
|
||||||
|
|
||||||
int socket;
|
int socket;
|
||||||
RelayConnProcs procs;
|
RelayConnProcs procs;
|
||||||
|
@ -75,12 +78,36 @@ static size_t writeVLI( XP_U8* out, uint32_t nn );
|
||||||
static size_t un2vli( int nn, uint8_t* buf );
|
static size_t un2vli( int nn, uint8_t* buf );
|
||||||
static bool vli2un( const uint8_t** inp, uint32_t* outp );
|
static bool vli2un( const uint8_t** inp, uint32_t* outp );
|
||||||
|
|
||||||
|
static void* relayThread( void* arg );
|
||||||
|
|
||||||
typedef struct _WriteState {
|
typedef struct _WriteState {
|
||||||
gchar* ptr;
|
gchar* ptr;
|
||||||
size_t curSize;
|
size_t curSize;
|
||||||
} WriteState;
|
} WriteState;
|
||||||
|
|
||||||
|
typedef enum { POST, QUERY, } TaskType;
|
||||||
|
|
||||||
|
typedef struct _RelayTask {
|
||||||
|
TaskType typ;
|
||||||
|
RelayConStorage* storage;
|
||||||
|
WriteState ws;
|
||||||
|
union {
|
||||||
|
struct {
|
||||||
|
XP_U8* msgbuf;
|
||||||
|
XP_U16 len;
|
||||||
|
} post;
|
||||||
|
struct {
|
||||||
|
GHashTable* map;
|
||||||
|
} query;
|
||||||
|
} u;
|
||||||
|
} RelayTask;
|
||||||
|
|
||||||
|
static RelayTask* makeRelayTask(RelayConStorage* storage, TaskType typ);
|
||||||
|
static void freeRelayTask(RelayTask* task);
|
||||||
|
static void handlePost( RelayTask* task );
|
||||||
|
static void handleQuery( RelayTask* task );
|
||||||
|
|
||||||
|
|
||||||
static size_t
|
static size_t
|
||||||
write_callback(void *contents, size_t size, size_t nmemb, void* data)
|
write_callback(void *contents, size_t size, size_t nmemb, void* data)
|
||||||
{
|
{
|
||||||
|
@ -138,8 +165,17 @@ relaycon_init( LaunchParams* params, const RelayConnProcs* procs,
|
||||||
XP_MEMCPY( &storage->procs, procs, sizeof(storage->procs) );
|
XP_MEMCPY( &storage->procs, procs, sizeof(storage->procs) );
|
||||||
storage->procsClosure = procsClosure;
|
storage->procsClosure = procsClosure;
|
||||||
|
|
||||||
|
if ( params->useHTTP ) {
|
||||||
storage->mainThread = pthread_self();
|
storage->mainThread = pthread_self();
|
||||||
|
pthread_mutex_init ( &storage->relayMutex, NULL );
|
||||||
|
pthread_cond_init( &storage->relayCondVar, NULL );
|
||||||
|
pthread_t thread;
|
||||||
|
(void)pthread_create( &thread, NULL, relayThread, storage );
|
||||||
|
pthread_detach( thread );
|
||||||
|
|
||||||
|
XP_ASSERT( XP_STRLEN(host) < VSIZE(storage->host) );
|
||||||
|
XP_MEMCPY( storage->host, host, XP_STRLEN(host) + 1 );
|
||||||
|
} else {
|
||||||
storage->socket = socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP );
|
storage->socket = socket( AF_INET, SOCK_DGRAM, IPPROTO_UDP );
|
||||||
(*procs->socketAdded)( storage, storage->socket, relaycon_receive );
|
(*procs->socketAdded)( storage, storage->socket, relaycon_receive );
|
||||||
|
|
||||||
|
@ -148,9 +184,7 @@ relaycon_init( LaunchParams* params, const RelayConnProcs* procs,
|
||||||
storage->saddr.sin_addr.s_addr = htonl( hostNameToIP(host) );
|
storage->saddr.sin_addr.s_addr = htonl( hostNameToIP(host) );
|
||||||
storage->saddr.sin_port = htons(port);
|
storage->saddr.sin_port = htons(port);
|
||||||
|
|
||||||
XP_ASSERT( XP_STRLEN(host) < VSIZE(storage->host) );
|
}
|
||||||
XP_MEMCPY( storage->host, host, XP_STRLEN(host) + 1 );
|
|
||||||
|
|
||||||
storage->params = params;
|
storage->params = params;
|
||||||
|
|
||||||
storage->proto = XWPDEV_PROTO_VERSION_1;
|
storage->proto = XWPDEV_PROTO_VERSION_1;
|
||||||
|
@ -311,6 +345,59 @@ onMainThread( RelayConStorage* storage )
|
||||||
return storage->mainThread = pthread_self();
|
return storage->mainThread = pthread_self();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void*
|
||||||
|
relayThread( void* arg )
|
||||||
|
{
|
||||||
|
RelayConStorage* storage = (RelayConStorage*)arg;
|
||||||
|
for ( ; ; ) {
|
||||||
|
pthread_mutex_lock( &storage->relayMutex );
|
||||||
|
while ( !storage->relayTaskList ) {
|
||||||
|
pthread_cond_wait( &storage->relayCondVar, &storage->relayMutex );
|
||||||
|
}
|
||||||
|
|
||||||
|
RelayTask* task = storage->relayTaskList->data;
|
||||||
|
storage->relayTaskList = storage->relayTaskList->next;
|
||||||
|
pthread_mutex_unlock( &storage->relayMutex );
|
||||||
|
|
||||||
|
switch ( task->typ ) {
|
||||||
|
case POST:
|
||||||
|
handlePost( task );
|
||||||
|
break;
|
||||||
|
case QUERY:
|
||||||
|
handleQuery( task );
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
XP_ASSERT(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
addTask( RelayConStorage* storage, RelayTask* task )
|
||||||
|
{
|
||||||
|
pthread_mutex_lock( &storage->relayMutex );
|
||||||
|
storage->relayTaskList = g_slist_append( storage->relayTaskList, task );
|
||||||
|
pthread_cond_signal( &storage->relayCondVar );
|
||||||
|
pthread_mutex_unlock( &storage->relayMutex );
|
||||||
|
}
|
||||||
|
|
||||||
|
static RelayTask*
|
||||||
|
makeRelayTask( RelayConStorage* storage, TaskType typ )
|
||||||
|
{
|
||||||
|
RelayTask* task = (RelayTask*)g_malloc0(sizeof(*task));
|
||||||
|
task->typ = typ;
|
||||||
|
task->storage = storage;
|
||||||
|
return task;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
freeRelayTask( RelayTask* task )
|
||||||
|
{
|
||||||
|
g_free( task->ws.ptr );
|
||||||
|
g_free( task );
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
sendAckIf( RelayConStorage* storage, const MsgHeader* header )
|
sendAckIf( RelayConStorage* storage, const MsgHeader* header )
|
||||||
{
|
{
|
||||||
|
@ -331,6 +418,7 @@ process( RelayConStorage* storage, XP_U8* buf, ssize_t nRead )
|
||||||
MsgHeader header;
|
MsgHeader header;
|
||||||
if ( readHeader( &ptr, &header ) ) {
|
if ( readHeader( &ptr, &header ) ) {
|
||||||
sendAckIf( storage, &header );
|
sendAckIf( storage, &header );
|
||||||
|
|
||||||
switch( header.cmd ) {
|
switch( header.cmd ) {
|
||||||
case XWPDEV_REGRSP: {
|
case XWPDEV_REGRSP: {
|
||||||
uint32_t len;
|
uint32_t len;
|
||||||
|
@ -433,6 +521,7 @@ relaycon_receive( GIOChannel* source, GIOCondition XP_UNUSED_DBG(condition), gpo
|
||||||
{
|
{
|
||||||
XP_ASSERT( 0 != (G_IO_IN & condition) ); /* FIX ME */
|
XP_ASSERT( 0 != (G_IO_IN & condition) ); /* FIX ME */
|
||||||
RelayConStorage* storage = (RelayConStorage*)data;
|
RelayConStorage* storage = (RelayConStorage*)data;
|
||||||
|
XP_ASSERT( !storage->params->useHTTP );
|
||||||
XP_U8 buf[512];
|
XP_U8 buf[512];
|
||||||
struct sockaddr_in from;
|
struct sockaddr_in from;
|
||||||
socklen_t fromlen = sizeof(from);
|
socklen_t fromlen = sizeof(from);
|
||||||
|
@ -494,17 +583,18 @@ hostNameToIP( const XP_UCHAR* name )
|
||||||
typedef struct _PostArgs {
|
typedef struct _PostArgs {
|
||||||
RelayConStorage* storage;
|
RelayConStorage* storage;
|
||||||
WriteState ws;
|
WriteState ws;
|
||||||
const XP_U8* msgbuf;
|
XP_U8* msgbuf;
|
||||||
XP_U16 len;
|
XP_U16 len;
|
||||||
} PostArgs;
|
} PostArgs;
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
onGotPostData(gpointer user_data)
|
onGotPostData(gpointer user_data)
|
||||||
{
|
{
|
||||||
PostArgs* pa = (PostArgs*)user_data;
|
RelayTask* task = (RelayTask*)user_data;
|
||||||
/* Now pull any data from the reply */
|
/* Now pull any data from the reply */
|
||||||
// got "{"status": "ok", "dataLen": 14, "data": "AYQDiDAyMUEzQ0MyADw=", "err": "none"}"
|
// got "{"status": "ok", "dataLen": 14, "data": "AYQDiDAyMUEzQ0MyADw=", "err": "none"}"
|
||||||
json_object* reply = json_tokener_parse( pa->ws.ptr );
|
if ( !!task->ws.ptr ) {
|
||||||
|
json_object* reply = json_tokener_parse( task->ws.ptr );
|
||||||
json_object* replyData;
|
json_object* replyData;
|
||||||
if ( json_object_object_get_ex( reply, "data", &replyData ) && !!replyData ) {
|
if ( json_object_object_get_ex( reply, "data", &replyData ) && !!replyData ) {
|
||||||
int len = json_object_array_length(replyData);
|
int len = json_object_array_length(replyData);
|
||||||
|
@ -513,25 +603,27 @@ onGotPostData(gpointer user_data)
|
||||||
const char* str = json_object_get_string( datum );
|
const char* str = json_object_get_string( datum );
|
||||||
gsize out_len;
|
gsize out_len;
|
||||||
guchar* buf = g_base64_decode( (const gchar*)str, &out_len );
|
guchar* buf = g_base64_decode( (const gchar*)str, &out_len );
|
||||||
process( pa->storage, buf, out_len );
|
process( task->storage, buf, out_len );
|
||||||
g_free( buf );
|
g_free( buf );
|
||||||
}
|
}
|
||||||
(void)json_object_put( replyData );
|
(void)json_object_put( replyData );
|
||||||
}
|
}
|
||||||
(void)json_object_put( reply );
|
(void)json_object_put( reply );
|
||||||
|
}
|
||||||
|
|
||||||
g_free( pa->ws.ptr );
|
g_free( task->u.post.msgbuf );
|
||||||
g_free( pa );
|
|
||||||
|
freeRelayTask( task );
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void*
|
static void
|
||||||
postThread( void* arg )
|
handlePost( RelayTask* task )
|
||||||
{
|
{
|
||||||
PostArgs* pa = (PostArgs*)arg;
|
XP_LOGF( "%s(len=%d)", __func__, task->u.post.len );
|
||||||
XP_ASSERT( !onMainThread(pa->storage) );
|
XP_ASSERT( !onMainThread(task->storage) );
|
||||||
char* data = g_base64_encode( pa->msgbuf, pa->len );
|
char* data = g_base64_encode( task->u.post.msgbuf, task->u.post.len );
|
||||||
struct json_object* jobj = json_object_new_object();
|
struct json_object* jobj = json_object_new_object();
|
||||||
struct json_object* jstr = json_object_new_string(data);
|
struct json_object* jstr = json_object_new_string(data);
|
||||||
g_free( data );
|
g_free( data );
|
||||||
|
@ -543,14 +635,14 @@ postThread( void* arg )
|
||||||
|
|
||||||
char url[128];
|
char url[128];
|
||||||
snprintf( url, sizeof(url), "%s://%s/xw4/relay.py/post",
|
snprintf( url, sizeof(url), "%s://%s/xw4/relay.py/post",
|
||||||
RELAY_API_PROTO, pa->storage->host );
|
RELAY_API_PROTO, task->storage->host );
|
||||||
curl_easy_setopt( curl, CURLOPT_URL, url );
|
curl_easy_setopt( curl, CURLOPT_URL, url );
|
||||||
curl_easy_setopt( curl, CURLOPT_POST, 1L );
|
curl_easy_setopt( curl, CURLOPT_POST, 1L );
|
||||||
|
|
||||||
addJsonParams( curl, "params", jobj );
|
addJsonParams( curl, "params", jobj );
|
||||||
|
|
||||||
curl_easy_setopt( curl, CURLOPT_WRITEFUNCTION, write_callback );
|
curl_easy_setopt( curl, CURLOPT_WRITEFUNCTION, write_callback );
|
||||||
curl_easy_setopt( curl, CURLOPT_WRITEDATA, &pa->ws );
|
curl_easy_setopt( curl, CURLOPT_WRITEDATA, &task->ws );
|
||||||
curl_easy_setopt( curl, CURLOPT_VERBOSE, 1L );
|
curl_easy_setopt( curl, CURLOPT_VERBOSE, 1L );
|
||||||
|
|
||||||
res = curl_easy_perform(curl);
|
res = curl_easy_perform(curl);
|
||||||
|
@ -563,41 +655,32 @@ postThread( void* arg )
|
||||||
curl_easy_cleanup(curl);
|
curl_easy_cleanup(curl);
|
||||||
curl_global_cleanup();
|
curl_global_cleanup();
|
||||||
|
|
||||||
XP_LOGF( "%s(): got \"%s\"", __func__, pa->ws.ptr );
|
XP_LOGF( "%s(): got \"%s\"", __func__, task->ws.ptr );
|
||||||
|
|
||||||
// Put the data on the main thread for processing
|
// Put the data on the main thread for processing
|
||||||
(void)g_idle_add( onGotPostData, pa );
|
(void)g_idle_add( onGotPostData, task );
|
||||||
|
} /* handlePost */
|
||||||
return NULL;
|
|
||||||
} /* postThread */
|
|
||||||
|
|
||||||
static ssize_t
|
static ssize_t
|
||||||
post( RelayConStorage* storage, const XP_U8* msgbuf, XP_U16 len )
|
post( RelayConStorage* storage, const XP_U8* msgbuf, XP_U16 len )
|
||||||
{
|
{
|
||||||
PostArgs* pa = (PostArgs*)g_malloc0(sizeof(*pa));
|
XP_LOGF( "%s(len=%d)", __func__, len );
|
||||||
pa->storage = storage;
|
RelayTask* task = makeRelayTask( storage, POST );
|
||||||
pa->msgbuf = msgbuf;
|
task->u.post.msgbuf = g_malloc(len);
|
||||||
pa->len = len;
|
XP_MEMCPY( task->u.post.msgbuf, msgbuf, len );
|
||||||
|
task->u.post.len = len;
|
||||||
pthread_t thread;
|
addTask( storage, task );
|
||||||
(void)pthread_create( &thread, NULL, postThread, (void*)pa );
|
|
||||||
pthread_detach( thread );
|
|
||||||
return len;
|
return len;
|
||||||
}
|
}
|
||||||
|
|
||||||
typedef struct _QueryArgs {
|
|
||||||
RelayConStorage* storage;
|
|
||||||
/* GSList* ids; */
|
|
||||||
WriteState ws;
|
|
||||||
GHashTable* map;
|
|
||||||
} QueryArgs;
|
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
onGotQueryData( gpointer user_data )
|
onGotQueryData( gpointer user_data )
|
||||||
{
|
{
|
||||||
QueryArgs* qa = (QueryArgs*)user_data;
|
RelayTask* task = (RelayTask*)user_data;
|
||||||
|
RelayConStorage* storage = task->storage;
|
||||||
XP_Bool foundAny = false;
|
XP_Bool foundAny = false;
|
||||||
json_object* reply = json_tokener_parse( qa->ws.ptr );
|
if ( !!task->ws.ptr ) {
|
||||||
|
json_object* reply = json_tokener_parse( task->ws.ptr );
|
||||||
if ( !!reply ) {
|
if ( !!reply ) {
|
||||||
CommsAddrRec addr = {0};
|
CommsAddrRec addr = {0};
|
||||||
addr_addType( &addr, COMMS_CONN_RELAY );
|
addr_addType( &addr, COMMS_CONN_RELAY );
|
||||||
|
@ -607,7 +690,7 @@ onGotQueryData( gpointer user_data )
|
||||||
int len1 = json_object_array_length( arrOfArrOfMoves );
|
int len1 = json_object_array_length( arrOfArrOfMoves );
|
||||||
XP_LOGF( "%s: got key: %s of len %d", __func__, relayID, len1 );
|
XP_LOGF( "%s: got key: %s of len %d", __func__, relayID, len1 );
|
||||||
if ( len1 > 0 ) {
|
if ( len1 > 0 ) {
|
||||||
sqlite3_int64 rowid = *(sqlite3_int64*)g_hash_table_lookup( qa->map, relayID );
|
sqlite3_int64 rowid = *(sqlite3_int64*)g_hash_table_lookup( task->u.query.map, relayID );
|
||||||
for ( int ii = 0; ii < len1; ++ii ) {
|
for ( int ii = 0; ii < len1; ++ii ) {
|
||||||
json_object* forGameArray = json_object_array_get_idx( arrOfArrOfMoves, ii );
|
json_object* forGameArray = json_object_array_get_idx( arrOfArrOfMoves, ii );
|
||||||
int len2 = json_object_array_length( forGameArray );
|
int len2 = json_object_array_length( forGameArray );
|
||||||
|
@ -616,7 +699,7 @@ onGotQueryData( gpointer user_data )
|
||||||
const char* asStr = json_object_get_string( oneMove );
|
const char* asStr = json_object_get_string( oneMove );
|
||||||
gsize out_len;
|
gsize out_len;
|
||||||
guchar* buf = g_base64_decode( asStr, &out_len );
|
guchar* buf = g_base64_decode( asStr, &out_len );
|
||||||
(*qa->storage->procs.msgForRow)( qa->storage->procsClosure, &addr,
|
(*storage->procs.msgForRow)( storage->procsClosure, &addr,
|
||||||
rowid, buf, out_len );
|
rowid, buf, out_len );
|
||||||
g_free(buf);
|
g_free(buf);
|
||||||
foundAny = XP_TRUE;
|
foundAny = XP_TRUE;
|
||||||
|
@ -626,25 +709,27 @@ onGotQueryData( gpointer user_data )
|
||||||
}
|
}
|
||||||
json_object_put( reply );
|
json_object_put( reply );
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ( foundAny ) {
|
if ( foundAny ) {
|
||||||
/* Reschedule. If we got anything this time, check again sooner! */
|
/* Reschedule. If we got anything this time, check again sooner! */
|
||||||
reset_schedule_check_interval( qa->storage );
|
reset_schedule_check_interval( storage );
|
||||||
}
|
}
|
||||||
schedule_next_check( qa->storage );
|
schedule_next_check( storage );
|
||||||
|
|
||||||
g_hash_table_destroy( qa->map );
|
g_hash_table_destroy( task->u.query.map );
|
||||||
g_free( qa );
|
freeRelayTask(task);
|
||||||
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void*
|
static void
|
||||||
queryThread( void* arg )
|
handleQuery( RelayTask* task )
|
||||||
{
|
{
|
||||||
QueryArgs* qa = (QueryArgs*)arg;
|
XP_ASSERT( !onMainThread(task->storage) );
|
||||||
XP_ASSERT( !onMainThread(qa->storage) );
|
|
||||||
GList* ids = g_hash_table_get_keys( qa->map );
|
if ( g_hash_table_size( task->u.query.map ) > 0 ) {
|
||||||
|
GList* ids = g_hash_table_get_keys( task->u.query.map );
|
||||||
|
|
||||||
json_object* jIds = json_object_new_array();
|
json_object* jIds = json_object_new_array();
|
||||||
for ( GList* iter = ids; !!iter; iter = iter->next ) {
|
for ( GList* iter = ids; !!iter; iter = iter->next ) {
|
||||||
|
@ -659,19 +744,18 @@ queryThread( void* arg )
|
||||||
|
|
||||||
char url[128];
|
char url[128];
|
||||||
snprintf( url, sizeof(url), "%s://%s/xw4/relay.py/query",
|
snprintf( url, sizeof(url), "%s://%s/xw4/relay.py/query",
|
||||||
RELAY_API_PROTO, qa->storage->host );
|
RELAY_API_PROTO, task->storage->host );
|
||||||
curl_easy_setopt(curl, CURLOPT_URL, url );
|
curl_easy_setopt(curl, CURLOPT_URL, url );
|
||||||
curl_easy_setopt(curl, CURLOPT_POST, 1L);
|
curl_easy_setopt(curl, CURLOPT_POST, 1L);
|
||||||
|
|
||||||
addJsonParams( curl, "ids", jIds );
|
addJsonParams( curl, "ids", jIds );
|
||||||
|
|
||||||
curl_easy_setopt( curl, CURLOPT_WRITEFUNCTION, write_callback );
|
curl_easy_setopt( curl, CURLOPT_WRITEFUNCTION, write_callback );
|
||||||
curl_easy_setopt( curl, CURLOPT_WRITEDATA, &qa->ws );
|
curl_easy_setopt( curl, CURLOPT_WRITEDATA, &task->ws );
|
||||||
curl_easy_setopt( curl, CURLOPT_VERBOSE, 1L );
|
curl_easy_setopt( curl, CURLOPT_VERBOSE, 1L );
|
||||||
|
|
||||||
res = curl_easy_perform( curl );
|
res = curl_easy_perform( curl );
|
||||||
|
|
||||||
XP_LOGF( "%s(): curl_easy_perform() => %d", __func__, res );
|
|
||||||
/* Check for errors */
|
/* Check for errors */
|
||||||
if (res != CURLE_OK) {
|
if (res != CURLE_OK) {
|
||||||
XP_LOGF( "curl_easy_perform() failed: %s", curl_easy_strerror(res));
|
XP_LOGF( "curl_easy_perform() failed: %s", curl_easy_strerror(res));
|
||||||
|
@ -680,13 +764,12 @@ queryThread( void* arg )
|
||||||
curl_easy_cleanup(curl);
|
curl_easy_cleanup(curl);
|
||||||
curl_global_cleanup();
|
curl_global_cleanup();
|
||||||
|
|
||||||
XP_LOGF( "%s(): got <<%s>>", __func__, qa->ws.ptr );
|
XP_LOGF( "%s(): got <<%s>>", __func__, task->ws.ptr );
|
||||||
|
|
||||||
|
}
|
||||||
/* Put processing back on the main thread */
|
/* Put processing back on the main thread */
|
||||||
g_idle_add( onGotQueryData, qa );
|
g_idle_add( onGotQueryData, task );
|
||||||
|
} /* handleQuery */
|
||||||
return NULL;
|
|
||||||
} /* queryThread */
|
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
checkForMoves( gpointer user_data )
|
checkForMoves( gpointer user_data )
|
||||||
|
@ -695,23 +778,10 @@ checkForMoves( gpointer user_data )
|
||||||
RelayConStorage* storage = (RelayConStorage*)user_data;
|
RelayConStorage* storage = (RelayConStorage*)user_data;
|
||||||
XP_ASSERT( onMainThread(storage) );
|
XP_ASSERT( onMainThread(storage) );
|
||||||
|
|
||||||
QueryArgs* qa = (QueryArgs*)g_malloc0(sizeof(*qa));
|
RelayTask* task = makeRelayTask( storage, QUERY );
|
||||||
qa->storage = storage;
|
|
||||||
|
|
||||||
sqlite3* dbp = storage->params->pDb;
|
sqlite3* dbp = storage->params->pDb;
|
||||||
// qa->map = getRowsToRelayIDsMap( dbp );
|
task->u.query.map = getRelayIDsToRowsMap( dbp );
|
||||||
qa->map = getRelayIDsToRowsMap( dbp );
|
addTask( storage, task );
|
||||||
// qa->ids = g_hash_table_get_values( qa->map );
|
|
||||||
/* for ( GList* iter = values; !!iter; iter = iter->next ) { */
|
|
||||||
/* gpointer data = iter->data; */
|
|
||||||
/* XP_LOGF( "checkForMoves: got id: %s", (char*)data ); */
|
|
||||||
/* qa->ids = g_slist_prepend( qa->ids, g_strdup(data) ); */
|
|
||||||
/* } */
|
|
||||||
/* g_list_free( values ); */
|
|
||||||
|
|
||||||
pthread_t thread;
|
|
||||||
(void)pthread_create( &thread, NULL, queryThread, (void*)qa );
|
|
||||||
pthread_detach( thread );
|
|
||||||
|
|
||||||
schedule_next_check( storage );
|
schedule_next_check( storage );
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
Loading…
Add table
Reference in a new issue