[dmd-concurrency] What is protected by synchronization?
Michel Fortin
michel.fortin at michelf.com
Sat Jan 30 06:57:13 PST 2010
Since we're talking about synchronization again, I think this is a problem that should be addressed.
As a general rule, we should make sure that pointers to variables of a synchronized class do not escape the (synchronized) member functions. Otherwise someone else will have non-synchronized access to them.
The problem is defining what is protected by the lock. Well, I don't think it's really a problem. Anything not explicitly declared shared should be protected by the lock. For instance, if you have this field:
shared(int)*[] data;
then the 'int' part is shared and can be visible from elsewhere, but any reference to the '*[]' part should be accessible only through synchronization and not allowed to escape outside a synchronization block (or a synchronized function).
So let's take a look at an example. I've made a class with a simple data structure with some data manipulation functions to evaluate what various designs could allow and disallow:
synchronized class A {
shared(int)*[] data;
void initialize() {
data = new shared(int)*[10];
foreach (d; data) {
d = new shared(int);
*d = random();
}
}
void sortByPointer() {
sort!"a > b"(data);
}
void sortByInteger() {
sort!"*a > *b"(data);
}
shared(int)* getOneOfThem() {
return data[0];
// ok: *data[0] is not protected by the lock
// so it can escape.
}
}
How can this work for sort? Sort receives an argument of type shared(int)*[], but how can it guaranty that no pointer will escape the function?
I'd like to have a way to call sort safely, but I'm under the impression that it's not possible without adding a lot of things to the type system (lent with ownership or scope restrictions). Any idea?
--
Michel Fortin
michel.fortin at michelf.com
http://michelf.com/
More information about the dmd-concurrency
mailing list