Thread overview
Synchronized statement causes IPF or hangs
Oct 04, 2004
Stewart Gordon
Oct 04, 2004
h3r3tic
Oct 04, 2004
Stewart Gordon
October 04, 2004
Using DMD 0.102, Windows 98SE.

If a statement block is synchronized but not against any object, and the statement is executed more than once in the course of the program, then an invalid page fault occurs when the program exits.

I created a few testcases, and these two both show the problem:

----------
import std.stdio;

void main() {
	for (int i = 0; i < 2; i++) {
		synchronized writefln("Running, time %d", i);
	}
}
----------
import std.stdio;

void main() {
	for (int i = 0; i < 2; i++) {
		Qwert yuiop = new Qwert;

		yuiop.print(i);
	}
}

class Qwert {
	void print(int i) {
		synchronized writefln("Running, time %d", i);
	}
}
----------
SYNC1 caused an invalid page fault in
module KERNEL32.DLL at 0167:bff8ac13.
Registers:
EAX=00000000 CS=0167 EIP=bff8ac13 EFLGS=00000246
EBX=00540000 SS=016f ESP=0064fde4 EBP=0064fdf0
ECX=00414a30 DS=016f ESI=00414a34 FS=46df
EDX=00414a30 ES=016f EDI=004149f8 GS=527e
Bytes at CS:EIP:
a1 10 9d fc bf 50 e8 96 95 fe ff ff 76 04 e8 35
Stack dump:
86a721d0 0040225a 00414a34 0064fe38 00408f28 00000000 0040986f 00540000 851c057c 004076b6 851c057c 00000000 86a721d0 00540000 00407604 0064fe10
----------

I also tried the same within a static method, but it hung the whole MS-DOS window it was running in and then confused Windows, without generating any output.  I haven't tried running it again as yet, but here it is:

----------
import std.stdio;

void main() {
    for (int i = 0; i < 2; i++) {
        Qwert.print(i);
    }
}

class Qwert {
    static void print(int i) {
        synchronized writefln("Running, time %d", i);
    }
}
----------

The following, OTOH, all ran and exited without error:

----------
import std.stdio;

void main() {
    for (int i = 0; i < 2; i++) {
        Qwert.print(i);
    }
}

class Qwert {
    static synchronized void print(int i) {
        writefln("Running, time %d", i);
    }
}
----------
import std.stdio;

void main() {
    for (int i = 0; i < 2; i++) {
        Qwert yuiop = new Qwert;

        yuiop.print(i);
    }
}

class Qwert {
    void print(int i) {
        synchronized (this) writefln("Running, time %d", i);
    }
}
----------
import std.stdio;

void main() {
    for (int i = 0; i < 2; i++) {
        Qwert yuiop = new Qwert;

        yuiop.print(i);
    }
}

class Qwert {
    synchronized void print(int i) {
        writefln("Running, time %d", i);
    }
}
----------

I don't know why the 'static synchronized' method works, but I suppose it's a useful workaround.

I haven't yet tried it with nested functions or anything fancy like that.

Stewart.
October 04, 2004
Stewart Gordon wrote:
> Using DMD 0.102, Windows 98SE.
> 
> If a statement block is synchronized but not against any object, and the statement is executed more than once in the course of the program, then an invalid page fault occurs when the program exits.
> 

I've reported the exact same behaviour a long time ago. I was told to synchronize only against an object. If that's the case, then why do the other cases work at all ?
/me confused
October 04, 2004
h3r3tic wrote:

> Stewart Gordon wrote:
> 
>> Using DMD 0.102, Windows 98SE.
>>
>> If a statement block is synchronized but not against any object, and the statement is executed more than once in the course of the program, then an invalid page fault occurs when the program exits.
> 
> I've reported the exact same behaviour a long time ago. I was told to synchronize only against an object.

If it were only meant to work against an object, then the form

    synchronized Statement

wouldn't be valid syntax.  As it happens, this is supposed to synchronize against Statement itself.

But as Carlos has pointed out, we already seem to have another CFG shortcoming here.

> If that's the case, then why do the other cases work at all ?
> /me confused

I guess that within a class,

    synchronized void qwert() { ... }

is syntactic sugar for

    void qwert() { synchronized (this) { ... } }

but that doesn't explain why static synchronized works, or at least seems to work.

Stewart.