Jerry Quinn wrote: > Jonathan M Davis Wrote: > >> On Saturday, September 24, 2011 01:05:52 Jerry Quinn wrote: >> > Jonathan M Davis Wrote: >> > > On Friday, September 23, 2011 23:01:17 Jerry Quinn wrote: >> > > >> > > A direct rewrite would involve using shared and synchronized (either >> > > on the class or a synchronized block around the code that you want to >> > > lock). However, the more idiomatic way to do it would be to use >> > > std.concurrency and have the threads pass messages to each other >> > > using send and receive. >> > >> > I'm trying the direct rewrite but having problems with shared and >> > synchronized. >> > >> > class queue { >> > File file; >> > this(string infile) { >> > file.open(infile); >> > } >> > synchronized void put(string s) { >> > file.writeln(s); >> > } >> > } >> > >> > queue.d(10): Error: template std.stdio.File.writeln(S...) does not >> > match any function template declaration queue.d(10): Error: template >> > std.stdio.File.writeln(S...) cannot deduce template function from >> > argument types !()(string) >> > >> > Remove the synchronized and it compiles fine with 2.055. >> >> Technically, sychronized should go on the _class_ and not the function, >> but I'm not sure if dmd is currently correctly implemented in that >> respect (since if it is, it should actually be an error to stick >> synchronized on a function). Regardless of that, however, unless you use >> shared (I don't know if you are), each instance of queue is going to be >> on its own thread. So, no mutexes will be necessary, but you won't be >> able to have multiple threads writing to the same File. It could get >> messy. > > I get similar errors if I put synchronized on the class, or shared. My > best guess is that a File struct cannot currently (2.055) be shared or > accessed in a synchronized context. > > If I make the class synchronized and use __gshared on the File then it > compiles. I don't know if it works, though.
You could embed a File pointer in the synchronized queue, make sure it is the sole owner, and then cast to File* when using it. The concurrency chapter has a paragraph on this method that explains why it is not covered by the type system. I believe this is closest to your C++ example, I never did this though so I'm not 100% sure it works.