There is a type of locking pattern that solves this issue.  It involves locks that can be in &quot;read&quot;, &quot;write&quot; or &quot;shared&quot; mode.  The concept is that you get a shared lock when you might want to upgrade to a write lock.<br>
<br>Shared mode can coexist with other threads that are in &quot;read&quot; mode, but is not compatible with other threads that are in write or shared mode.  You can upgrade a shared mode lock to a write lock without deadlocking -- it waits for other threads to finish reading.<br>
<br>The normal usage pattern is that you get a shared mode when you might want to modify something.  Let&#39;s say that a user wants to write a line to a logfile.  You get a shared mode lock on the directory, then check if the file exists.  If it already exists, you downgrade the shared lock to a read lock, then get a write mode lock on the file.  If the file does not exist, you instead upgrade the shared lock to a write lock, then create the file (which is why you needed write permissions), then get a write lock on the new file and downgrade or release the directory lock.<br>
<br>This model of locking cannot deadlock on itself because there is only
one &quot;shared&quot;
process at a time -- when getting a shared lock, you need to wait for all existing writers to exit, and for any existing shared lock holders to exit or downgrade.  It works best for cases where
a processes often thinks it *might* need to do a write operation but usually doesn&#39;t, in which case it reduces lock contention for reader threads.  The most common situation is where you don&#39;t know if you need to do the write until you&#39;ve done some reads to asses the current situation.<br>
<br>I know we used locks like this when I was at IBM.  I wish I could find out who invented this so I know whether it is patented.  (IBM loves patents -- I suspect it isn&#39;t patented but I haven&#39;t found a good writeup of it online yet.)<br>
<br>Kevin<br><br><div class="gmail_quote">On Wed, Jan 20, 2010 at 7:28 AM, Michel Fortin <span dir="ltr">&lt;<a href="mailto:michel.fortin@michelf.com">michel.fortin@michelf.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
Le 2010-01-20 à 2:07, Sean Kelly a écrit :<br>
<div class="im"><br>
&gt; Is what you want in core.sync.rwmutex?  You can use it as:<br>
&gt;<br>
&gt; synchronized( mut.reader ) {}<br>
&gt; synchronized( mut.writer ) {}<br>
&gt;<br>
&gt; It doesn&#39;t currently allow upgrading read locks to write locks, though I think this wouldn&#39;t be difficult to add.  More importantly I suppose is that acquiring a concurrent read lock may be more expensive than you&#39;d expect, so you really only want to use a ReadWriteMutex if the read operations take a reasonable amount of time to complete.<br>

<br>
</div>What happens if you call test() here?<br>
<br>
        void test() {<br>
                synchronized (mut.reader) {<br>
                        // read A<br>
                        testWrite();<br>
                        // read B<br>
                }<br>
        }<br>
<br>
        void testWrite() {<br>
                syncrhonized (mut.writer) {<br>
                        // write C<br>
                }<br>
        }<br>
<br>
I guess that if you haven&#39;t implemented upgrades this will deadlock.<br>
<br>
I&#39;d like to note that even upgrading the lock to a write lock might be a problem: as I said in my other message, making this an automatic upgrade might force the release the reader lock until the writer lock is acquired, which would be unexpected from test()&#39;s point of view.<br>

<br>
This could work well as a transaction, where a failure to upgrade the lock would throw an exception, &quot;read A&quot; would be rollbacked, and the synchronized part would be attempted again. But without proper logic to deal with the unfortunate case of a failed upgrade you have either a race or a deadlock here.<br>

<div class="im"><br>
--<br>
Michel Fortin<br>
<a href="mailto:michel.fortin@michelf.com">michel.fortin@michelf.com</a><br>
<a href="http://michelf.com/" target="_blank">http://michelf.com/</a><br>
<br>
<br>
<br>
_______________________________________________<br>
</div><div><div></div><div class="h5">dmd-concurrency mailing list<br>
<a href="mailto:dmd-concurrency@puremagic.com">dmd-concurrency@puremagic.com</a><br>
<a href="http://lists.puremagic.com/mailman/listinfo/dmd-concurrency" target="_blank">http://lists.puremagic.com/mailman/listinfo/dmd-concurrency</a><br>
</div></div></blockquote></div><br>