It took me 17 minutes this morning to figure where si->wait_event was
set (it's in si_reset() which should now probably be renamed since it
doesn't just perform a reset anymore but also an allocation) and what
its task was assigned to (si_cs_io_cb() even for applets and empty SI).
This is too confusing and not intuitive enough, let's at least add a
few comments for now to help figure how this stuff works next time.
return did_send;
}
+/* This is the ->process() function for any stream-interface's wait_event task.
+ * It's assigned during the stream-interface's initialization, for any type of
+ * stream interface. Thus it is always safe to perform a tasklet_wakeup() on a
+ * stream interface, as the presence of the CS is checked there.
+ */
struct task *si_cs_io_cb(struct task *t, void *ctx, unsigned short state)
{
struct stream_interface *si = ctx;
if (!cs)
return NULL;
-redo:
+
if (!(si->wait_event.wait_reason & SUB_CAN_SEND) && co_data(si_oc(si)))
ret = si_cs_send(cs);
if (!(si->wait_event.wait_reason & SUB_CAN_RECV))