0
0
mirror of https://github.com/cjdelisle/cjdns synced 2025-10-06 00:32:50 +02:00
Files
cjdns/admin/angel/InterfaceWaiter.c
2017-01-14 00:57:12 +02:00

85 lines
2.5 KiB
C

/* vim: set expandtab ts=4 sw=4: */
/*
* You may redistribute this program and/or modify it under the terms of
* the GNU General Public License as published by the Free Software Foundation,
* either version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
#include "admin/angel/InterfaceWaiter.h"
#include "exception/Except.h"
#include "memory/Allocator.h"
#include "util/events/EventBase.h"
#include "util/log/Log.h"
#include "io/FileWriter.h"
#include "util/events/Timeout.h"
struct Context
{
struct Iface iface;
struct EventBase* eventBase;
struct Message* message;
struct Allocator* alloc;
struct Timeout* timeout;
int timedOut;
int messageReceived;
Identity
};
static void timeout(void* vcontext)
{
struct Context* ctx = vcontext;
ctx->timedOut = 1;
EventBase_endLoop(ctx->eventBase);
}
static Iface_DEFUN receiveMessage(struct Message* message, struct Iface* iface)
{
struct Context* ctx = Identity_check((struct Context*) iface);
if (ctx->messageReceived) { return 0; }
ctx->message = Message_clone(message, ctx->alloc);
Timeout_clearTimeout(ctx->timeout);
EventBase_endLoop(ctx->eventBase);
return 0;
}
struct Message* InterfaceWaiter_waitForData(struct Iface* iface,
struct EventBase* eventBase,
struct Allocator* alloc,
struct Except* eh)
{
struct Context ctx = {
.iface = { .send = receiveMessage },
.eventBase = eventBase,
.alloc = alloc
};
Identity_set(&ctx);
Iface_plumb(iface, &ctx.iface);
struct Allocator* tempAlloc = Allocator_child(alloc);
ctx.timeout = Timeout_setTimeout(timeout, &ctx, 10000, eventBase, tempAlloc);
EventBase_beginLoop(eventBase);
Iface_unplumb(iface, &ctx.iface);
Allocator_free(tempAlloc);
if (ctx.timedOut) {
Except_throw(eh, "InterfaceWaiter Timed out waiting for data.");
}
Assert_true(!iface->connectedIf);
Assert_true(ctx.message);
return ctx.message;
}