#ifdef JANET #include "Extensions/Internal.h" typedef struct ExtensionStanzaReply { pthread_mutex_t lock; pthread_cond_t cond; XMLElement *stanza; Extension *ext; bool reply, ack; char *type; } ExtensionStanzaReply; static void OnStanzaResponse(JanetEVGenericMessage msg) { ExtensionStanzaReply *reply = msg.argp; Extension *ext = reply->ext; Janet args[2] = { ExtensionsFromXML(NULL, reply->stanza), janet_cstringv(reply->type) }; Janet ret; if (TryCall(ext, "on-stanza", 2, args, &ret)) { pthread_mutex_lock(&reply->lock); reply->ack = true; reply->reply = janet_truthy(ret); pthread_cond_signal(&reply->cond); pthread_mutex_unlock(&reply->lock); return; } pthread_mutex_lock(&reply->lock); reply->ack = true; reply->reply = false; pthread_cond_signal(&reply->cond); pthread_mutex_unlock(&reply->lock); } bool ExtensionPushStanza(Extensions *ctx, XMLElement *stanza, StanzaType t) { bool veto = false; size_t i; char *table[STANZA_TYPE_COUNT] = { "raw", "message", "iq", "presence" }; char *key; Extension *val; if (!ctx || !stanza) { return false; } pthread_mutex_lock(&ctx->mtx); for (i = 0; IterateReentrant(ctx->extensions, key, val, i); ) { ExtensionStanzaReply *reply = Malloc(sizeof(*reply)); JanetEVGenericMessage msg = { /* We except a veto boolean. */ .tag = JANET_STANZA_PUSH, }; pthread_mutex_init(&reply->lock, NULL); pthread_cond_init(&reply->cond, NULL); reply->ext = val; reply->reply = false; reply->ack = false; reply->type = table[t]; reply->stanza = stanza; msg.argp = reply; janet_ev_post_event(val->vm, OnStanzaResponse, msg); pthread_mutex_lock(&reply->lock); while (!reply->ack) { pthread_cond_wait(&reply->cond, &reply->lock); } pthread_mutex_unlock(&reply->lock); pthread_mutex_destroy(&reply->lock); pthread_cond_destroy(&reply->cond); if (reply->reply) { veto = true; } Free(reply); } pthread_mutex_unlock(&ctx->mtx); return veto; } #endif