fr_message_set_t *ms; //!< message buffers for this socket.
fr_channel_data_t *cd; //!< cached in case of allocation & read error
size_t leftover; //!< leftover data from a previous read
+ size_t written; //!< however much we did in a partial write
fr_channel_data_t *pending; //!< the currently pending partial packet
fr_heap_t *waiting; //!< packets waiting to be written
rad_assert(s->pending != NULL);
+ /*
+ * @todo - this code is much the same as in
+ * fr_network_post_event(). Fix it so we only have one
+ * copy!
+ */
+
/*
* Start with the currently pending message, and then
* work through the priority heap.
* pending message to the current one.
*/
if (errno == EWOULDBLOCK) {
+ s->pending = 0;
+
+ save_pending:
+ /*
+ * s->pending MUST be localized.
+ * Other messages in the list
+ * MUST NOT have been localized
+ * yet.
+ */
+ if (cd->m.status != FR_MESSAGE_LOCALIZED) {
+ fr_message_t *lm;
+
+ MEM(lm = fr_message_localize(s, &cd->m, sizeof(*cd)));
+ fr_message_done(&cd->m);
+
+ cd = (fr_channel_data_t *) lm;
+ }
s->pending = cd;
return;
}
}
/*
- *
- We MUST have written all of the data. It is
- * up to the app_io->write() function to track
- * any partially written data.
+ * If we've done a partial write, localize the message and continue.
*/
- rad_assert((size_t) rcode == cd->m.data_size);
+ if ((rcode > 0) && ((size_t) rcode < cd->m.data_size)) {
+ s->written = rcode;
+ goto save_pending;
+ }
+
s->pending = NULL;
+ s->written = 0;
/*
* Reset for the next message.
cd->reply.request_time,
cd->m.data, cd->m.data_size, 0);
if (rcode < 0) {
+ s->pending = 0;
+
+ save_pending:
if (errno == EWOULDBLOCK) {
if (fr_event_fd_insert(nr, nr->el, s->fd,
fr_network_read,
}
/*
- * We MUST have written all of the data. It is
- * up to the app_io->write() function to track
- * any partially written data.
+ * If there's a partial write, save the write
+ * callback for later.
*/
- rad_assert(!rcode || (size_t) rcode == cd->m.data_size);
+ if ((rcode > 0) && ((size_t) rcode < cd->m.data_size)) {
+ s->written = rcode;
+ goto save_pending;
+ }
DEBUG3("Sending reply to socket %d", s->fd);
fr_message_done(&cd->m);
+ s->pending = NULL;
+ s->written = 0;
/*
* As a special case, allow write() to return