I've never understood benefit of hiding mutexes like that Java construct does. It even does so in three different ways depending on how it's used. Is the code somehow made more clear because the mutexes disappear? I prefer to see them, so I can tell easily which regions are synchronized with each other. That also makes it easier to search on the mutex variable to find those regions.
There's one benefit with a block construct like that: It makes the region where the lock is held more clear. (The pike way of relying on refcount garbing of the lock has lead to many bugs, e.g. with the tail recursion optimization. I don't rely on refcounting for locks anymore; I always zero them explicitly afterwards.)
So in my view a good synchronized construct would always require a mutex argument. E.g:
Thread.Mutex my_mutex = Thread.Mutex(); synchronized(my_mutex) void my_first_function() {...}
void my_second_function() { ... synchronized(my_mutex) { ... } }
The second case above is solvable with implicit lambda, but I'd rather avoid implementing it that way since it "destroys" the syntax so it can't be upgraded to a better implementation later on (see the blurb about implicit lambdas in the CHANGES file).
As a transitionary measure, we could perhaps have something like this instead that works through implicit lambdas:
my_mutex->synchronize() { ... };
/ Martin Stjernholm, Roxen IS
Previous text:
2003-02-04 19:14: Subject: synchronized
One thing that's nice in Java is the 'synchronized keyword. It would be nice to have that functionality in Pike since it's easier than manually using mutex locks (nicer code):
synchronized void do_something() { ... }
and
mapping foo; void do_something() { synchronized(foo) { work on foo } }
and
void do_something() { ... synchronized { locked region } ... }
would be nice. The first one creates an implicit mutex lock for the entire method, the second one creates a lock bound to a specific variable (i.e you can have multiple methods "locking" the same variable) and the third method works just like the first, except for a specific region rather than the entire method.
Another possibility is to have synchronized classes:
synchronized class { ... }
and variable instanses:
synchronized mapping foo = ([]);
But the first three versions are IMHO more interesting.
How hard would this be to implement in pike? I'm guessing "quite hard", but... :)
/ David Hedbor