June 04, 2012
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
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
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
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
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
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
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
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
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
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...
16 17 18 19 20 21 22 23 24 25 26
Next ›   Last »