On 2012-06-05 01:58:04 +0000, "Jason House" <[email protected]> said:

I was thinking something more like this:

shared class Dictionary
{
   private SynchronizedCounters counters;
   private SynchronizedStringMap translations(counters);

   void addWord(string word, string foreignWord) shared
   {
     // synchronized opIndexAssign call
     translations[word] = foreignWord;
   }
   bool confirmWord(string word, string foreignWord) shared
   {
     // synchronized opIndex call
     string candidate = translations[word];
     if (candidate != foreignWord)
       return false;
     counters.confirmOneWord();
     globalNotifyWordConfirmed(word, foreignWord);
     return true;
   }
}

// All counter operations are embedded here
// No need to review for any unsafe data usage,
// it's all here (future uses will add new methods)
synchronized class SynchronizedCounters
{
   private int confirmed, unconfirmed;
   void addUnconfirmed() { ++unconfirmed; }
   void confirmOneWord() { --unconfirmed; ++confirmed; }
}

// Similar concept, but embeds SynchronizedCounters
// I don't like that, but it's the only way to fully
// embrace D synchronized classes for toy example
synchronized class SynchronizedStringMap
{
   private string[string] translations;
   private SynchronizedCounters counters;
   this(SynchronizedCounters _counters)
     : counters(_counters) {}
   void opIndexAssign(string word, string foreignWord)
   {
     translations[word] = foreignWord;
     counters.addUnconfirmed();
   }
   string opIndex(string word)
   {
     shared string *found = word in translations;
     if (found)
       return *found;
     else
       return null;
   }
}

I see there are some errors, but I get the general concept.

And I can see why you don't like that. It's no longer a "SynchronizedStringMap" once it contains the counters: it's just a shell encapsulating the parts of Dictionary that needs to be run while the mutex is locked. Because you can't lock Dictionary since it has callbacks, you have to split code that would normally be together and put the synchronized portion in another class just to fit the constrains of the synchronized class concept. I think this illustrates that associating mutexes to variables is a better approach.

Beside, I wouldn't want to be the one who has to teach about writing concurrent code using this paradigm. Even the equivalent C++ code is easier to read and explain that this; shouldn't that raise a red flag?


--
Michel Fortin
[email protected]
http://michelf.com/

Reply via email to