Scope ExecObjects with Tokens
The original PrepareFor*
methods of ArrayHandle
returned an object to
be used in the execution environment on a particular device that pointed to
data in the array. The pointer to the data was contingent on the state of
the ArrayHandle
not changing. The assumption was that the calling code
would next use the returned execution environment object and would not
further change the ArrayHandle
until done with the execution environment
object.
This assumption is broken if multiple threads are running in the control
environment. After one thread has called PrepareFor*
and is in the
process of using the resulting execution object and another thread attempts
to write to or otherwise change the same array.
Because we cannot use the object itself to manage its own resources, we use
a proxy object we are calling a Token
. The Token
object manages the
scope of the return execution object. As long as the Token
is still in
scope, the execution object will remain valid. When the Token
is
destroyed (or DetachFromAll
is called on it), then the execution object
is no longer protected.
When a Token
is attached to an ArrayHandle
to protect an execution
object, it's read or write mode is recorded. Multiple Token
s can be
attached to read the ArrayHandle
at the same time. However, only one
Token
can be used to write to the ArrayHandle
.