June 04, 2012 Re: synchronized (this[.classinfo]) in druntime and phobos | ||||
---|---|---|---|---|
| ||||
Posted in reply to deadalnix Attachments:
| On Sun, Jun 3, 2012 at 5:13 PM, deadalnix <deadalnix@gmail.com> wrote: > Le 04/06/2012 02:03, Andrew Wiley a écrit : > >> On Sun, Jun 3, 2012 at 4:39 PM, deadalnix <deadalnix@gmail.com >> >> <mailto:deadalnix@gmail.com>> wrote: >> >> Le 03/06/2012 21:40, Andrew Wiley a écrit : >> >> On Sun, Jun 3, 2012 at 12:29 PM, deadalnix <deadalnix@gmail.com >> <mailto:deadalnix@gmail.com> >> <mailto:deadalnix@gmail.com <mailto:deadalnix@gmail.com>>> wrote: >> >> Le 01/06/2012 22:55, Sean Kelly a écrit : >> >> On Jun 1, 2012, at 5:26 AM, deadalnix wrote: >> >> >> The main drawback is the same as opApply : return (and >> break/continue but it is less relevant for >> opSynchronized). >> Solution to this problem have been proposed in the past >> using compiler and stack magic. >> >> It open door for stuff like : >> ReadWriteLock rw; >> synchronized(rw.read) { >> >> } >> >> synchronized(rw.write) { >> >> } >> >> >> Opens the door? This works today exactly as outlined >> above. Or >> am I missing a part of your argument? >> >> And many types of lock : spin lock, interprocesses >> locks, >> semaphores, . . . And all can be used with the >> synchronized >> syntax, and without exposing locking and unlocking >> primitives. >> >> >> All works today. >> >> >> Unless you do some monitor magic, it doesn't. >> >> Yes, it does. >> ----- >> class Something { >> private: >> ReadWriteLock _rw; >> public: >> this() { >> _rw = new ReadWriteLock(); >> } >> void doSomething() shared { >> synchronized(_rw.read) { >> // do things >> } >> } >> } >> ----- >> I've used this pattern in code. There might be some casting >> required >> because the core synchronization primitives haven't been updated >> to use >> shared yet. >> >> >> And where is that ReadWriteLock ? >> >> On the GC heap, just like the Monitor object pointed to by __monitor if you mark a method or class as synchronized. >> > > I meant where is the code ? > My apologies, it's actually ReadWriteMutex: http://dlang.org/phobos/core_sync_rwmutex.html |
June 04, 2012 Re: synchronized (this[.classinfo]) in druntime and phobos | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrew Wiley | On 04-06-2012 02:03, Andrew Wiley wrote: > On Sun, Jun 3, 2012 at 4:39 PM, deadalnix <deadalnix@gmail.com > <mailto:deadalnix@gmail.com>> wrote: > > Le 03/06/2012 21:40, Andrew Wiley a écrit : > > On Sun, Jun 3, 2012 at 12:29 PM, deadalnix <deadalnix@gmail.com > <mailto:deadalnix@gmail.com> > <mailto:deadalnix@gmail.com <mailto:deadalnix@gmail.com>>> wrote: > > Le 01/06/2012 22:55, Sean Kelly a écrit : > > On Jun 1, 2012, at 5:26 AM, deadalnix wrote: > > > The main drawback is the same as opApply : return (and > break/continue but it is less relevant for > opSynchronized). > Solution to this problem have been proposed in the past > using compiler and stack magic. > > It open door for stuff like : > ReadWriteLock rw; > synchronized(rw.read) { > > } > > synchronized(rw.write) { > > } > > > Opens the door? This works today exactly as outlined > above. Or > am I missing a part of your argument? > > And many types of lock : spin lock, interprocesses > locks, > semaphores, . . . And all can be used with the > synchronized > syntax, and without exposing locking and unlocking > primitives. > > > All works today. > > > Unless you do some monitor magic, it doesn't. > > Yes, it does. > ----- > class Something { > private: > ReadWriteLock _rw; > public: > this() { > _rw = new ReadWriteLock(); > } > void doSomething() shared { > synchronized(_rw.read) { > // do things > } > } > } > ----- > I've used this pattern in code. There might be some casting required > because the core synchronization primitives haven't been updated > to use > shared yet. > > > And where is that ReadWriteLock ? > > On the GC heap, just like the Monitor object pointed to by __monitor if > you mark a method or class as synchronized. The monitor in obj.__monitor is actually allocated on the native C heap, and, in some cases, leaked... one of the many reasons I want it gone. -- Alex Rønne Petersen alex@lycus.org http://lycus.org |
June 04, 2012 Re: synchronized (this[.classinfo]) in druntime and phobos | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrew Wiley | Le 04/06/2012 02:21, Andrew Wiley a écrit :
> On Sun, Jun 3, 2012 at 5:13 PM, deadalnix <deadalnix@gmail.com
> <mailto:deadalnix@gmail.com>> wrote:
>
> Le 04/06/2012 02:03, Andrew Wiley a écrit :
>
> On Sun, Jun 3, 2012 at 4:39 PM, deadalnix <deadalnix@gmail.com
> <mailto:deadalnix@gmail.com>
>
> <mailto:deadalnix@gmail.com <mailto:deadalnix@gmail.com>>> wrote:
>
> Le 03/06/2012 21:40, Andrew Wiley a écrit :
>
> On Sun, Jun 3, 2012 at 12:29 PM, deadalnix
> <deadalnix@gmail.com <mailto:deadalnix@gmail.com>
> <mailto:deadalnix@gmail.com <mailto:deadalnix@gmail.com>>
> <mailto:deadalnix@gmail.com <mailto:deadalnix@gmail.com>
> <mailto:deadalnix@gmail.com <mailto:deadalnix@gmail.com>>>> wrote:
>
> Le 01/06/2012 22:55, Sean Kelly a écrit :
>
> On Jun 1, 2012, at 5:26 AM, deadalnix wrote:
>
>
> The main drawback is the same as opApply :
> return (and
> break/continue but it is less relevant for
> opSynchronized).
> Solution to this problem have been proposed
> in the past
> using compiler and stack magic.
>
> It open door for stuff like :
> ReadWriteLock rw;
> synchronized(rw.read) {
>
> }
>
> synchronized(rw.write) {
>
> }
>
>
> Opens the door? This works today exactly as
> outlined
> above. Or
> am I missing a part of your argument?
>
> And many types of lock : spin lock,
> interprocesses
> locks,
> semaphores, . . . And all can be used with the
> synchronized
> syntax, and without exposing locking and
> unlocking
> primitives.
>
>
> All works today.
>
>
> Unless you do some monitor magic, it doesn't.
>
> Yes, it does.
> -----
> class Something {
> private:
> ReadWriteLock _rw;
> public:
> this() {
> _rw = new ReadWriteLock();
> }
> void doSomething() shared {
> synchronized(_rw.read) {
> // do things
> }
> }
> }
> -----
> I've used this pattern in code. There might be some
> casting required
> because the core synchronization primitives haven't been
> updated
> to use
> shared yet.
>
>
> And where is that ReadWriteLock ?
>
> On the GC heap, just like the Monitor object pointed to by
> __monitor if
> you mark a method or class as synchronized.
>
>
> I meant where is the code ?
>
> My apologies, it's actually ReadWriteMutex:
> http://dlang.org/phobos/core_sync_rwmutex.html
Which does use monitor magic.
|
June 04, 2012 Re: synchronized (this[.classinfo]) in druntime and phobos | ||||
---|---|---|---|---|
| ||||
Posted in reply to Regan Heath | Am 31.05.2012 17:05, schrieb Regan Heath:
> .. but, hang on, can a thread actually lock a and then b? If 'a' cannot participate in a synchronized statement (which it can't under this proposal) then no, there is no way to lock 'a' except by calling a member. So, provided 'a' does not have a member which locks 'b' - were deadlock safe!
>
> So.. problem solved; by preventing external/public lock/unlock on a synchronized class. (I think the proposal should enforce this restriction; synchronized classes cannot define __lock/__unlock).
>
> R
>
I think it doesn't matter whether you expose your mointor / locking / unlocking to the public or not. You can always unhappily create deadlocks that are hard to debug between tons of spaghetti code.
shared A a;
shared B b;
void thread1()
{
synchronized(a) // locks A
{
synchronized(b) // ... then B
{
// ..... code ....
}
}
}
void thread2()
{
synchronized(b) // locks B
{
synchronized(a) // ... then A
{
// ..... code ....
}
}
}
|
June 04, 2012 Re: synchronized (this[.classinfo]) in druntime and phobos | ||||
---|---|---|---|---|
| ||||
Posted in reply to mta`chrono | On Monday, June 04, 2012 10:51:08 mta`chrono wrote:
> Am 31.05.2012 17:05, schrieb Regan Heath:
> > .. but, hang on, can a thread actually lock a and then b? If 'a' cannot participate in a synchronized statement (which it can't under this proposal) then no, there is no way to lock 'a' except by calling a member. So, provided 'a' does not have a member which locks 'b' - were deadlock safe!
> >
> > So.. problem solved; by preventing external/public lock/unlock on a synchronized class. (I think the proposal should enforce this restriction; synchronized classes cannot define __lock/__unlock).
> >
> > R
>
> I think it doesn't matter whether you expose your mointor / locking / unlocking to the public or not. You can always unhappily create deadlocks that are hard to debug between tons of spaghetti code.
You can always create deadlocks, but if there's something which gives you little benefit but significantly increases the risk of deadlocks (e.g. making it easy to lock on a synchronized class' internal mutex via a synchronized block), then it's valuable to make it illegal. Because while it won't prevent all deadlocking, it _does_ eliminate one case where it's overly easy to deadlock.
- Jonathan M Davis
|
June 04, 2012 Re: synchronized (this[.classinfo]) in druntime and phobos | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jonathan M Davis | Le 04/06/2012 10:56, Jonathan M Davis a écrit :
> On Monday, June 04, 2012 10:51:08 mta`chrono wrote:
>> Am 31.05.2012 17:05, schrieb Regan Heath:
>>> .. but, hang on, can a thread actually lock a and then b? If 'a' cannot
>>> participate in a synchronized statement (which it can't under this
>>> proposal) then no, there is no way to lock 'a' except by calling a
>>> member. So, provided 'a' does not have a member which locks 'b' - were
>>> deadlock safe!
>>>
>>> So.. problem solved; by preventing external/public lock/unlock on a
>>> synchronized class. (I think the proposal should enforce this
>>> restriction; synchronized classes cannot define __lock/__unlock).
>>>
>>> R
>>
>> I think it doesn't matter whether you expose your mointor / locking /
>> unlocking to the public or not. You can always unhappily create
>> deadlocks that are hard to debug between tons of spaghetti code.
>
> You can always create deadlocks, but if there's something which gives you
> little benefit but significantly increases the risk of deadlocks (e.g. making it
> easy to lock on a synchronized class' internal mutex via a synchronized
> block), then it's valuable to make it illegal. Because while it won't prevent
> all deadlocking, it _does_ eliminate one case where it's overly easy to
> deadlock.
>
> - Jonathan M Davis
At least illegal by default. The programmer may enable it by him/herself, but not fall in the trap inadvertently.
|
June 06, 2012 Re: synchronized (this[.classinfo]) in druntime and phobos | ||||
---|---|---|---|---|
| ||||
Posted in reply to Alex Rønne Petersen | On Tuesday, 29 May 2012 at 22:01:50 UTC, Alex Rønne Petersen wrote:
> On 29-05-2012 23:54, Andrei Alexandrescu wrote:
>> On 5/29/12 2:49 PM, Alex Rønne Petersen wrote:
>
> It doesn't, and neither does C#. Java still encourages using synchronized, and C# still encourages using lock, but many prominent figures in those programming language communities have written blog posts on why these language constructs are evil and should be avoided.
>
> Besides, it seems to me that D can't quite make up its mind. We have TLS by default, and we encourage message-passing (through a library mechanism), and then we have the synchronized statement and attribute. It just seems so incredibly inconsistent. synchronized encourages doing the wrong thing (locks and synchronization).
I can't remember having read those blog posts. I agree message passing is a better abstraction, but I haven't read Josh Bloch, for example, saying "don't use synchronized".
|
June 06, 2012 Re: synchronized (this[.classinfo]) in druntime and phobos | ||||
---|---|---|---|---|
| ||||
Posted in reply to deadalnix | On Jun 3, 2012, at 12:29 PM, deadalnix wrote:
> Le 01/06/2012 22:55, Sean Kelly a écrit :
>> On Jun 1, 2012, at 5:26 AM, deadalnix wrote:
>>>
>>> The main drawback is the same as opApply : return (and break/continue but it is less relevant for opSynchronized). Solution to this problem have been proposed in the past using compiler and stack magic.
>>>
>>> It open door for stuff like :
>>> ReadWriteLock rw;
>>> synchronized(rw.read) {
>>>
>>> }
>>>
>>> synchronized(rw.write) {
>>>
>>> }
>>
>> Opens the door? This works today exactly as outlined above. Or am I missing a part of your argument?
>>
>>> And many types of lock : spin lock, interprocesses locks, semaphores, . . . And all can be used with the synchronized syntax, and without exposing locking and unlocking primitives.
>>
>> All works today.
>
> Unless you do some monitor magic, it doesn't.
There is a bit of cleverness in there.
|
June 06, 2012 Re: synchronized (this[.classinfo]) in druntime and phobos | ||||
---|---|---|---|---|
| ||||
Posted in reply to Alex Rønne Petersen | On Jun 3, 2012, at 5:24 PM, Alex Rønne Petersen wrote:
>
> The monitor in obj.__monitor is actually allocated on the native C heap, and, in some cases, leaked... one of the many reasons I want it gone.
The benefit of it being on the native C heap is that you can use synchronized{} in the object's dtor. You can't do this if the monitor is on the GC heap, as Mutex is.
|
June 09, 2012 Re: synchronized (this[.classinfo]) in druntime and phobos | ||||
---|---|---|---|---|
| ||||
Posted in reply to deadalnix | deadalnix , dans le message (digitalmars.D:169136), a écrit :
> It open door for stuff like :
> ReadWriteLock rw;
> synchronized(rw.read) {
>
> }
>
> synchronized(rw.write) {
>
> }
>
> And many types of lock : spin lock, interprocesses locks, semaphores, . . . And all can be used with the synchronized syntax, and without exposing locking and unlocking primitives.
>
synchronize (foo) { ... } could do anything.
You might as well propose a syntax sugar to call any function or method taking a delegate. You could make it do any operation with the idiom:
struct MyType {
void foo(void delegate() dg) {
this.open();
scope(exit) this.close();
dg();
}
...
}
a.foo { // maybe some keyword should be necessary
...
}
Same problem as opApply, should take different type of delegates, etc...
|
Copyright © 1999-2021 by the D Language Foundation