[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