/* for all pending requests */ bool more_requests; do {
more_requests = false;
list_for_every_entry_safe(&hwrng_req_list, ctx, temp, struct hwrng_chan_ctx, node) { if (ctx->error || ctx->send_blocked) continue; /* can't service it right now */
/* *senduptoMAX_HWRNG_MSG_SIZEperclientatatime, *topreventasingleclientfromstarvingalltheothers
*/
size_t len = MIN(ctx->req_size, MAX_HWRNG_MSG_SIZE); if (rng_data_avail_count) { /* use leftover data if there is any */
len = MIN(len, rng_data_avail_count);
} else { /* get hwrng data */
rand_get_bytes(rng_data, len);
rng_data_avail_pos = 0;
rng_data_avail_count = len;
}
/* send reply */
rc = ktipc_send(ctx->chan, rng_data + rng_data_avail_pos, len); if (rc < 0) { if (rc == ERR_NOT_ENOUGH_BUFFER) { /* mark it as send_blocked */
ctx->send_blocked = true;
} else {
TRACEF("%s: failed (%d) to send_reply\n", __func__, rc);
ctx->error = rc;
} continue;
}
/* check for an error from a previous send attempt */ if (ctx->error) { return ctx->error;
}
/* read request */
rc = ktipc_recv(chan, sizeof(req), &req, sizeof(req)); if (rc < 0) {
TRACEF("%s: failed (%d) to receive msg for chan\n", __func__, rc); return rc;
}
/* check if we already have request in progress */ if (list_in_list(&ctx->node)) { /* extend it */
ctx->req_size += req.len;
} else { /* queue it */
ctx->req_size = req.len;
list_add_tail(&hwrng_req_list, &ctx->node);
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.