SC_FL_ISBACK = 0x00000001, /* Set for SC on back-side */
SC_FL_EOI = 0x00000002, /* End of input was reached. no more data will be received from the endpoint */
- /* not used: 0x00000004 */
+ SC_FL_ERROR = 0x00000004, /* A fatal error was reported */
SC_FL_NOLINGER = 0x00000008, /* may close without lingering. One-shot. */
SC_FL_NOHALF = 0x00000010, /* no half close, close both sides at once */
/* prologue */
_(0);
/* flags */
- _(SC_FL_ISBACK, _(SC_FL_EOI, _(SC_FL_NOLINGER, _(SC_FL_NOHALF,
+ _(SC_FL_ISBACK, _(SC_FL_EOI, _(SC_FL_ERROR, _(SC_FL_NOLINGER, _(SC_FL_NOHALF,
_(SC_FL_DONT_WAKE, _(SC_FL_INDEP_STR, _(SC_FL_WONT_READ,
_(SC_FL_NEED_BUFF, _(SC_FL_NEED_ROOM,
_(SC_FL_RCV_ONCE, _(SC_FL_SND_ASAP, _(SC_FL_SND_NEVERWAIT, _(SC_FL_SND_EXP_MORE,
- _(SC_FL_ABRT_WANTED, _(SC_FL_SHUT_WANTED, _(SC_FL_ABRT_DONE, _(SC_FL_SHUT_DONE)))))))))))))))));
+ _(SC_FL_ABRT_WANTED, _(SC_FL_SHUT_WANTED, _(SC_FL_ABRT_DONE, _(SC_FL_SHUT_DONE))))))))))))))))));
/* epilogue */
_(~0U);
return buf;
sockaddr_free(&s->scb->dst);
sc_set_state(s->scb, SC_ST_INI);
- s->scb->flags &= ~(SC_FL_SHUT_DONE|SC_FL_SHUT_WANTED);
+ s->scb->flags &= ~(SC_FL_ERROR|SC_FL_SHUT_DONE|SC_FL_SHUT_WANTED);
s->scb->flags &= SC_FL_ISBACK | SC_FL_DONT_WAKE; /* we're in the context of process_stream */
s->req.flags &= ~(CF_AUTO_CONNECT|CF_STREAMER|CF_STREAMER_FAST|CF_WROTE_DATA);
s->store_count = 0;
s->uniq_id = global.req_count++;
- s->scf->flags &= ~(SC_FL_ABRT_DONE|SC_FL_ABRT_WANTED);
+ s->scf->flags &= ~(SC_FL_ERROR|SC_FL_ABRT_DONE|SC_FL_ABRT_WANTED);
s->scf->flags &= ~SC_FL_SND_NEVERWAIT;
s->scf->flags |= SC_FL_RCV_ONCE; /* one read is usually enough */
res->analyse_exp = TICK_ETERNITY;
res->total = 0;
- s->scb->flags &= ~(SC_FL_SHUT_DONE|SC_FL_SHUT_WANTED);
+ s->scb->flags &= ~(SC_FL_ERROR|SC_FL_SHUT_DONE|SC_FL_SHUT_WANTED);
if (sc_reset_endp(s->scb) < 0) {
if (!(s->flags & SF_ERR_MASK))
s->flags |= SF_ERR_INTERNAL;
ret = 1;
}
- if (sc_ep_test(sc, SE_FL_ERROR))
+ if (sc_ep_test(sc, SE_FL_ERROR)) {
+ sc->flags |= SC_FL_ERROR;
ret = 1;
+ }
else if (!(sc->flags & (SC_FL_WONT_READ|SC_FL_NEED_BUFF|SC_FL_NEED_ROOM)) &&
!(sc->flags & SC_FL_ABRT_DONE)) {
/* Subscribe to receive events if we're blocking on I/O */
if (sc_ep_test(sc, SE_FL_ERROR | SE_FL_ERR_PENDING)) {
oc->flags |= CF_WRITE_EVENT;
BUG_ON(sc_ep_test(sc, SE_FL_EOS|SE_FL_ERROR|SE_FL_ERR_PENDING) == (SE_FL_EOS|SE_FL_ERR_PENDING));
+ if (sc_ep_test(sc, SE_FL_ERROR))
+ sc_ep_set(sc, SC_FL_ERROR);
return 1;
}
*/
if (sc->state >= SC_ST_CON) {
- if (sc_is_conn_error(sc))
+ if (sc_is_conn_error(sc)) {
sc_ep_set(sc, SE_FL_ERROR);
+ sc->flags |= SC_FL_ERROR;
+ }
}
/* If we had early data, and the handshake ended, then
ic->flags |= CF_READ_EVENT;
}
+ if (sc_ep_test(sc, SE_FL_ERROR))
+ sc->flags |= SC_FL_ERROR;
+
/* Second step : update the stream connector and channels, try to forward any
* pending data, then possibly wake the stream up based on the new
* stream connector status.
ic->flags |= CF_READ_EVENT;
}
+ if (sc_ep_test(sc, SE_FL_ERROR))
+ sc->flags |= SC_FL_ERROR;
+
if (sc_ep_test(sc, SE_FL_EOS)) {
/* we received a shutdown */
sc_abort(sc);