Struggling with shared objects

Jonathan M Davis via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Sat Jan 17 15:18:40 PST 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



More information about the Digitalmars-d-learn mailing list