On 08/16, Roland McGrath wrote: > > > Whatever we do, start_callback() can see the old engine->flags but > > the new ->ops = &utrace_detached_ops. Just suppose that the caller > > of UTRACE_DETACH is interrupted right after setting engine->ops. > > * it can check the old flags before using the old ops, or check the old > * flags before using the new ops, or check the new flags before using the > * new ops, but can never check the new flags before using the old ops. > > > Or do you think I miss something and this is false alarm? > > * Hence, utrace_detached_ops might be used with any old flags in place. > * It has report_quiesce() and report_reap() callbacks to handle all cases. > > report_reap is covered with the utrace_detached_reap() stub. Every other > callback uses start_callback(), i.e. calls report_quiesce first. > utrace_detached_quiesce() returns UTRACE_DETACH,
Assuming ->report_quiesce() will be called. Suppose that, say, engine->flags == UTRACE_EVENT(EXEC) (no QUIESCE). 1. start_callback() reads want = engine->flags (== EXEC) 2. mark_engine_detached() sets engine->ops = &utrace_detached_ops 3. start_callback() gets ops = utrace_detached_ops After that start_callback() skips "if (want & UTRACE_EVENT(QUIESCE))" block and returns utrace_detached_ops, utrace_detached_ops->report_exec == NULL will be called. But this is minor. Roland, I can't explain this, but I have the strong gut feeling there is something else we should worry about. I am still reading this code... Oleg.