digitalmars.D.learn - Struggling with shared objects
- Mike (14/14) Jan 17 2015 Hey, all.
- Vlad Levenfeld (5/5) Jan 17 2015 That's real weird.
- Mike (14/19) Jan 17 2015 It is during compilation.
- Mike (4/4) Jan 17 2015 Oh, I said "the moment I call"
- anonymous (11/26) Jan 17 2015 I don't get what `auto message = client.receive(buf);` is
- Mike (12/12) Jan 17 2015 Ha, I am so stupid! I forgot to call the socket member before
- Jonathan M Davis via Digitalmars-d-learn (57/69) Jan 17 2015 Very little in the standard library is currently going to be usable as
- Mike (3/3) Jan 17 2015 Thank you so much!
Hey, all. I have just started using D and I'm really loving it, but I have been caught on a problem. I am trying to share my Client class to a new thread, and after a bit of struggling: I finally got the code to compile! Now I am having a new problem: the moment I call "client.receive(buf)" I get an error: D:\D\dmd2\src\phobos\std\concurrency.d(13,13): Error: static assert (false || false) is false (StompBroker) I assume it has something to do with the way I am handling the shared keyword along with pointers, but I cannot for the life of me figure this out! Any help is appreciated. Thank you! Code: https://github.com/mvlipka/StompBroker
Jan 17 2015
That's real weird. In D:\D\dmd2\src\phobos\std\concurrency.d(13,13) 13,13 isn't a line number and static assertions should go off during compilation, not runtime.
Jan 17 2015
On Saturday, 17 January 2015 at 21:12:34 UTC, Vlad Levenfeld wrote:That's real weird. In D:\D\dmd2\src\phobos\std\concurrency.d(13,13) 13,13 isn't a line number and static assertions should go off during compilation, not runtime.It is during compilation. When I run dmd myself, I get this: C:\Users\Michael\Documents\Projects\StompBroker\StompBroker>dmd main.d D:\D\dmd2\windows\bin\..\..\src\phobos\std\concurrency.d(165): Error: static ass ert (false || false) is false D:\D\dmd2\windows\bin\..\..\src\phobos\std\concurrency.d(634): instantiat ed from here: checkops!(shared(Client*), char[1024]) main.d(11): instantiated from here: receive!(shared(Client*), char[1024])
Jan 17 2015
Oh, I said "the moment I call" I should have reworded that. I meant that the moment I add that line to the code, I get the error. Sorry!
Jan 17 2015
On Saturday, 17 January 2015 at 21:00:34 UTC, Mike wrote:Hey, all. I have just started using D and I'm really loving it, but I have been caught on a problem. I am trying to share my Client class to a new thread, and after a bit of struggling: I finally got the code to compile! Now I am having a new problem: the moment I call "client.receive(buf)" I get an error: D:\D\dmd2\src\phobos\std\concurrency.d(13,13): Error: static assert (false || false) is false (StompBroker) I assume it has something to do with the way I am handling the shared keyword along with pointers, but I cannot for the life of me figure this out! Any help is appreciated. Thank you! Code: https://github.com/mvlipka/StompBrokerI don't get what `auto message = client.receive(buf);` is supposed to call exactly. If you mean to call std.concurrency.receive [1], it's way off. That's what the error message complains about. If you mean to call a method of Client, well it doesn't have a `receive` method. Also, you have too many asterisks (*). Classes already have reference semantics in D. There's no need for `Socket*` or `Client`. Just use `Socket` and `Client`.
Jan 17 2015
Ha, I am so stupid! I forgot to call the socket member before receive! Thank you for the help. I have also removed the pointers. I am now getting this: C:\Users\Michael\Documents\Projects\StompBroker\StompBroker>dmd main.d main.d(11): Error: None of the overloads of 'receive' are callable using a shared object, candidates are: D:\D\dmd2\windows\bin\..\..\src\phobos\std\socket.d(2897):std.socket.S cket.receive(void[] buf, SocketFlags flags) D:\D\dmd2\windows\bin\..\..\src\phobos\std\socket.d(2912):std.socket.S cket.receive(void[] buf)
Jan 17 2015
On Saturday, January 17, 2015 21:56:56 Mike via Digitalmars-d-learn wrote:Ha, I am so stupid! I forgot to call the socket member before receive! Thank you for the help. I have also removed the pointers. I am now getting this: C:\Users\Michael\Documents\Projects\StompBroker\StompBroker>dmd main.d main.d(11): Error: None of the overloads of 'receive' are callable using a shared object, candidates are: D:\D\dmd2\windows\bin\..\..\src\phobos\std\socket.d(2897):std.socket.Socket.receive(void[] buf, SocketFlags flags) D:\D\dmd2\windows\bin\..\..\src\phobos\std\socket.d(2912):std.socket.Socket.receive(void[] buf)Very little in the standard library is currently going to be usable as shared. The only way that a member function can be called on a shared object is if the function is marked as shared, and pretty much nothing in the standard library is marked with shared. In theory, the idea is that when using shared, you'd use a synchronized class, and the outer layer of shared would get cast away on the member variables inside of the member functions (since the compiler could guarantee that nothing else has access to those member variables), but synchronized classes haven't been implemented, only synchronized functions. So, at present, there's nowhere in the language that implicitly casts away shared. What that means is that if you're using shared, you generally have to do something like shared T mySharedObject = getMySharedObjectFromSomewhere(); synchronized(objImSynchronizingOn) { auto nowUnshared = cast(T)mySharedObject; // do stuff with nowUnshared // make sure that nothing else has access to nowUnshared so that // unlocking it is safe. } // now it's no longer locked, and only the shared reference to the obeject // exists. And that's still an improvement over C++, because your shared code is segregated from your thread-local code, and you're protecting the shared stuff with locks similar to how you'd do in C++, but obviously, it's more annoying and error-prone than we'd like. In most cases, you just don't use shared unless you have to, and then you use the idiom that I just described. And in the case of sockets, you frequently only want them on one thread anyway, so I question that you really want those sockets to be living on a single thread, in which case, they don't need to be shared, but I don't know what you're doing, so having them be shared may be exactly what needs to happen. But regardless, in general, you should use shared as little as possible, and where you do use it, you're either forced to write functions which only operate on shared objects, or you have to cast away shared when the object is protected by a mutex. And really, you should be protecting with a mutex before you operate on it anyway, so the mutex or synchronized block portion of that is normal. It should just be the casting away of shared that's new and annoying if you're new to D. I'd suggest that you read the concurrency chapter in TDPL, since it's mostly correct, and it should give a decent idea of how to deal with threads and concurrency in D. The main problems with that chapter that I recall is that it claims that shared introduces memory barriers (which isn't currently true and will probably never be true due to the overhead that that would incur), and it describes synchronized classes, which we don't currently have (though AFAIK, the plan is still to add them at some point). Right now, we have synchronized functions like Java does, and TDPL specifically says that that's a bad idea and that synchronized classes are better (which may be true, but we don't have them yet). That chapter is one of the few that's available online if you don't own the book: http://www.informit.com/articles/article.aspx?p=1609144 though I'd advise that you pick up the book if you don't have it, since it's quite good and still mostly correct ( http://wiki.dlang.org/Differences_With_TDPL lists most of the differences). - Jonathan M Davis
Jan 17 2015
Thank you so much! I got it all working now. You're definitely right, that is still easier than C++.
Jan 17 2015