On Tuesday, 22 May 2018 at 23:09:24 UTC, Sjoerd Nijboer wrote:
On Tuesday, 22 May 2018 at 22:17:05 UTC, IntegratedDimensions
wrote:
On Tuesday, 22 May 2018 at 22:10:52 UTC, Alex wrote:
On Tuesday, 22 May 2018 at 21:45:07 UTC, IntegratedDimensions
wrote:
an idea to lock data by removing the reference:
class A
{
Lockable!Data data;
}
The idea is that when the data is going to be used, the user
locks the data. The trick here is that data is a pointer to
the data and the pointer is set to null when locked so no
other data can use it(they see a null reference). To unlock,
the data is reassigned:
auto d = data.lock(); // A.data is now null deals with sync
issues
//use d
d = data.unlock(d); // restores A.data (A.data = d;) and
sets d to null so any future reference is an error(could
produce bugs but should mostly be access violations)
Anyone else trying to use data will see that it is null
while it is locked.
This basically pushes the standard locking mechanisms in to
the Lockable!data(first come first serve) and code that has
not captured the data see's it simply as null.
Anyone use know if there exists an idiom like this and what
it is called? Maybe some idiomatic code that is efficient?
Ideally I'd want to be able to treat the Lockable!Data as
Data. Right now I have to classes(or pointers to structs)
and few weird hacks. I think what I'll have to end up doing
is having a Locked!Data structure that is returned instead
or use an UFCS. The idea being to attach the lock and unlock
methods.
Are you aware of NullableRef?
https://dlang.org/library/std/typecons/nullable_ref.html
Yes.
Does it fit somehow?
Not really. It could be used to wrap the data when used as a
struct but it offers none of the locking features which is the
ultimate goal.
The idea is simply that one can lock the data to get exclusive
access. Normally standard locking tricks are used but in this
case the idea is to do all that behind the scenes. Locking the
data makes all other accessors see null data(and crash or
properly test). This is a first come first serve or single
access type of pattern but sort of removes the data from
prying eyes while it is being used.
how about something like
import core.atomic;
class Lockable!Data
{
private __gshared Lockable!Data data;
}
struct Locked!Lockable!Data
{
private TailShared!Lockable!Data lockedData;
private Lockable!Data lockableData;
this(Lockable!Data lockableData)
{
this.lockableData = lockableData;
while( (lockedData= atomicLoad(lockableData)) !is null)
if(cas(lockedData, lockedData, null))
break;
}
~this()
{
atomicStore(lockedData, lockableData );
}
alias lockedData.data this;
}
With something like this you should be able to do RAII like
semantics on your data.
You share a Lockable!Data which you want use, and then you can
access it if you instantiate a Locked!Lockable!Data struct with
it.
FYI, my atomics isn't all that great so don't expect this to
work.
This is similar to what I am doing... maybe "identical".