[ADD/WIP] Timeouts in stanza awaiting

Querying for a MUC will not take longer than 10 seconds, now.
This commit is contained in:
LDA 2024-07-09 16:26:35 +02:00
commit d449c8097e
4 changed files with 52 additions and 12 deletions

View file

@ -15,7 +15,6 @@ XMPPQueryMUC(XMPPComponent *jabber, char *muc, MUCInfo *out)
char *uuid, *from; char *uuid, *from;
if (!jabber || !muc) if (!jabber || !muc)
{ {
Log(LOG_WARNING, ":(");
return false; return false;
} }
@ -40,8 +39,9 @@ XMPPQueryMUC(XMPPComponent *jabber, char *muc, MUCInfo *out)
StreamFlush(jabber->stream); StreamFlush(jabber->stream);
XMLFreeElement(iq_query); XMLFreeElement(iq_query);
/* Except an IQ reply */ /* Except an IQ reply. 10 seconds of timeout is pretty
iq_query = ParseeAwaitStanza(uuid); * generous, if you ask me. */
iq_query = ParseeAwaitStanza(uuid, 10 SECONDS);
Free(uuid); Free(uuid);
if (!iq_query || !StrEquals(iq_query->name, "iq")) if (!iq_query || !StrEquals(iq_query->name, "iq"))
{ {

View file

@ -65,6 +65,7 @@ ParseeMXID(ParseeData *data)
":", data->config->homeserver_host); ":", data->config->homeserver_host);
} }
/* Performs i;octet collation. */
static int static int
ICollate(unsigned char *cata, unsigned char *catb) ICollate(unsigned char *cata, unsigned char *catb)
{ {
@ -1453,8 +1454,11 @@ ParseeXMPPThread(void *argp)
pthread_mutex_destroy(&info.lock); pthread_mutex_destroy(&info.lock);
return NULL; return NULL;
} }
#include <time.h>
#include <errno.h>
XMLElement * XMLElement *
ParseeAwaitStanza(char *identifier) ParseeAwaitStanza(char *identifier, int64_t timeout)
{ {
/* TODO: Pthreads HATE me using Malloc here, so I'm abusing stackspace. /* TODO: Pthreads HATE me using Malloc here, so I'm abusing stackspace.
* Not *too much* of a problem, just a weird oddity. If anyone has a clue * Not *too much* of a problem, just a weird oddity. If anyone has a clue
@ -1462,11 +1466,24 @@ ParseeAwaitStanza(char *identifier)
* me know! */ * me know! */
XMPPAwait awa; XMPPAwait awa;
XMLElement *stanza; XMLElement *stanza;
struct timespec ts;
if (!identifier) if (!identifier)
{ {
return NULL; return NULL;
} }
if (timeout > 0)
{
int64_t seconds = timeout / (1 SECONDS);
int64_t msecond = timeout % (1 SECONDS);
clock_gettime(CLOCK_REALTIME, &ts);
ts.tv_sec += seconds ;
ts.tv_nsec+= msecond * 1000000 ;
}
pthread_mutex_lock(&await_lock); pthread_mutex_lock(&await_lock);
pthread_cond_init(&awa.condition, NULL); pthread_cond_init(&awa.condition, NULL);
@ -1479,8 +1496,20 @@ ParseeAwaitStanza(char *identifier)
pthread_mutex_lock(&awa.cond_lock); pthread_mutex_lock(&awa.cond_lock);
while (!awa.stanza) while (!awa.stanza)
{ {
/* TODO: Allow timeouts. */ int code;
pthread_cond_wait(&awa.condition, &awa.cond_lock);
if (timeout <= 0)
{
pthread_cond_wait(&awa.condition, &awa.cond_lock);
continue;
}
code = pthread_cond_timedwait(&awa.condition, &awa.cond_lock, &ts);
if (code == ETIMEDOUT)
{
/* Timeout detected, give up regardless of the status of our
* search. */
break;
}
} }
stanza = awa.stanza; stanza = awa.stanza;

View file

@ -115,8 +115,13 @@ extern void ParseeRequest(HttpServerContext *, void *);
/* A pthread callback used for listening to a component */ /* A pthread callback used for listening to a component */
extern void * ParseeXMPPThread(void *data); extern void * ParseeXMPPThread(void *data);
/* Wait for a specific stanza with an ID */ /** Wait for any stanza with an "id" attribute of {identifier},
extern XMLElement * ParseeAwaitStanza(char *identifier); * with an optional timeout in milliseconds of {ts} if it is positive.
* --------
* UB-If: called in the XMPP dispatcher thread itself
* Returns: NULL | XMLElement[LA:HEAP]
* Modifies: NONE */
extern XMLElement * ParseeAwaitStanza(char *identifier, int64_t ts);
/* Finds the room a DM is associated to, from a Matrix user and a Jabber /* Finds the room a DM is associated to, from a Matrix user and a Jabber
* ID. */ * ID. */

View file

@ -46,12 +46,18 @@ typedef struct MUCInfo {
XMLElement *iq_reply; XMLElement *iq_reply;
} MUCInfo; } MUCInfo;
/* Queries a MUC's existence, and if $[out] is set, stores information /** Queries a MUC's existence, and if {out} is set, stores information
* pertaining the MUC itself from an <iq> query, to be freed by * pertaining the MUC itself from an IQ query.
* XMPPFreeMUCInfo */ * ----------------------------------------------------------------------
* Modifies: *out[TBFB:XMPPFreeMUCInfo]
* See-Also: XMPPGetMUCName, XMPPFreeMUCInfo */
extern bool XMPPQueryMUC(XMPPComponent *jabber, char *muc, MUCInfo *out); extern bool XMPPQueryMUC(XMPPComponent *jabber, char *muc, MUCInfo *out);
/* Retrieves the MUC's name from an IQ reply */ /** Retrieves the MUC's name from an IQ reply
* ----------------------------------------------------------------------
* Returns: The MUC's name[LA:HEAP] | NULL
* Modifies: NOTHING
* See-Also: XMPPQueryMUC, XMPPFreeMUCInfo */
extern char * XMPPGetMUCName(MUCInfo info); extern char * XMPPGetMUCName(MUCInfo info);
extern void XMPPFreeMUCInfo(MUCInfo info); extern void XMPPFreeMUCInfo(MUCInfo info);