* Data only ever read or written by the main thread.
*/
bufchain queued_data; /* data still waiting to be written */
+ enum { EOF_NO, EOF_PENDING, EOF_SENT } outgoingeof;
/*
* Callback function called when the backlog in the bufchain
ctx->len = sendlen;
SetEvent(ctx->ev_from_main);
ctx->busy = TRUE;
+ } else if (!ctx->busy && bufchain_size(&ctx->queued_data) == 0 &&
+ ctx->outgoingeof == EOF_PENDING) {
+ CloseHandle(ctx->h);
+ ctx->h = INVALID_HANDLE_VALUE;
+ ctx->outgoingeof = EOF_SENT;
}
}
h->u.o.done = FALSE;
h->u.o.privdata = privdata;
bufchain_init(&h->u.o.queued_data);
+ h->u.o.outgoingeof = EOF_NO;
h->u.o.sentdata = sentdata;
h->u.o.flags = flags;
int handle_write(struct handle *h, const void *data, int len)
{
assert(h->output);
+ assert(h->u.o.outgoingeof == EOF_NO);
bufchain_add(&h->u.o.queued_data, data, len);
handle_try_output(&h->u.o);
return bufchain_size(&h->u.o.queued_data);
}
+void handle_write_eof(struct handle *h)
+{
+ /*
+ * This function is called when we want to proactively send an
+ * end-of-file notification on the handle. We can only do this by
+ * actually closing the handle - so never call this on a
+ * bidirectional handle if we're still interested in its incoming
+ * direction!
+ */
+ assert(h->output);
+ if (!h->u.o.outgoingeof == EOF_NO) {
+ h->u.o.outgoingeof = EOF_PENDING;
+ handle_try_output(&h->u.o);
+ }
+}
+
HANDLE *handle_get_events(int *nevents)
{
HANDLE *ret;