Closed burlog closed 3 years ago
I have duplicated the use-after-free when using the added sleep. The sleep allows the command to complete before making the final for loop condition check:
for (uint32_t i = 0; i < exec->max_concurrent; i++) {
Since the query completed, "exec" is no longer valid. The solution is to use a temporary variable, "max".
uint32_t max = exec->max_concurrent;
for (uint32_t i = 0; i < max; i++) {
There are a few more cases where this construct is used, so we will attempt to fix all of them in the next client release.
Hi Brian,
I have another uncertainty. I wonder if incrementing the queued attribute without any lock is valid.
for (uint32_t i = 0, m = exec->max_concurrent; i < m; i++) {
exec->queued++;
as_event_command* cmd = exec->commands[i];
as_status status = as_event_command_execute(cmd, err);
if (status != AEROSPIKE_OK) {
as_event_executor_cancel(exec, i);
break;
}
}
Sorry for closing, I mistakenly hit the Enter.
I think the "queued" increment is okay for queries because "queued" is only used when the query executor is destroyed. If the executor is destroyed, all commands must have finished or be cancelled from same original thread. If there are additional commands to to queue, all commands could not possibly be finished.
There is, however, a slight problem with "queued" for scans. Scan allows a concurrent policy where queries do not. If concurrent is false (not default), scans are executed sequentially and "queued" is incremented in both original thread and eventloop thread. This is unlikely to cause problems because the eventloop thread will read "queued" (value 1) from original thread on first use and then all further increments happen in the eventloop thread. It does look a bit awkward, so we will also investigate a more consistent way to handle "queued" in the next client release.
I see, thanks you for clarify.
C client 5.0.1 is released. The use-after-free condition is fixed, but the "queued" logic remains the same.
Prerequisites:
examples/async_examples/async_query/src/main/example.c
How to reproduce: