RejectedSoftware Forums

Sign up

Example of mutex use ?

As a beginner in D and Vibe programming I have a hard time finding code examples online.

I'm currently trying to find out how to use vibe's fiber friendly mutexes. Is the following code the correct way to use mutexes ? I suppose synchronizing on the object is nos OK because the mutex in the base object is not a fiber friendly mutex.

final class Store {
  auto mtx = new TaskMutex;
  int count = 0;
  // Return the incremented value of count in a string
  string getIncrementedCount()
  {
    synchronize(mtx) 
    {
      count += 1; 
      return to!string(count);
    }
  }
}

void get(HTTPServerRequest req, HTTPServerResponse res)
{
  string str = g_store.getIncrementedCount();
  render!"index.dt"(res, str);
}

shared Store g_store;

shared static this()
{
  g_store = new Store;
  auto router = new URLRouter;
  router.get("/", &get);
  auto settings = new HTTPServerSettings;
  settings.port = 8080;
  settings.bindAddresses = ["::1", "127.0.0.1"];
  listenHTTP(settings, router);
  logInfo("Open http://127.0.0.1:8080/ in your browser");
}

Re: Example of mutex use ?

Am 23.04.2016 um 20:39 schrieb chmike:

As a beginner in D and Vibe programming I have a hard time finding code examples online.

I'm currently trying to find out how to use vibe's fiber friendly mutexes. Is the following code the correct way to use mutexes ? I suppose synchronizing on the object is nos OK because the mutex in the base object is not a fiber friendly mutex.

final class Store {
   auto mtx = new TaskMutex;
   int count = 0;
   // Return the incremented value of count in a string
   string getIncrementedCount()
   {
     synchronize(mtx)
     {
       count += 1;
       return to!string(count);
     }
   }
}

Looks good, although in this specific case you wouldn't really need to
use a TaskMutex (it has some performance overhead). That is only
required if any blocking operations (I/O, receiving messages, sleeping,
yield'ing) take place while the mutex is locked. So if that's not the
case, using the object's own monitor is fine, too.

Re: Example of mutex use ?

On Wed, 27 Apr 2016 20:48:51 +0200, Sönke Ludwig wrote:

Looks good, although in this specific case you wouldn't really need to
use a TaskMutex (it has some performance overhead). That is only
required if any blocking operations (I/O, receiving messages, sleeping,
yield'ing) take place while the mutex is locked. So if that's not the
case, using the object's own monitor is fine, too.

Is the overhead important ? Is reading/writing data from/to disk considered a blocking I/O operation ?

I have to protect modifying and rendering data stored in a cache which may occasionally require access to a local disk. Should this be protected by an interruptible mutex or is a std D mutex OK?

Re: Example of mutex use ?

Unfortunately the code is not correct because the global variable is declared as shared. And this implies that the class must be synchronized.

As a consequence this is not compatible with vibe.d fibers since we should use vibe.d friendly fibers. The variable increment was a dummy operation for example. In practice it could be an operation doing blocking calls.

Re: Example of mutex use ?

On Sun, 01 May 2016 10:39:20 GMT, chmike wrote:

Unfortunately the code is not correct because the global variable is declared as shared. And this implies that the class must be synchronized.

As a consequence this is not compatible with vibe.d fibers since we should use vibe.d friendly fibers. The variable increment was a dummy operation for example. In practice it could be an operation doing blocking calls.

What you can do is to use setSameMutex to change the object monitor to a TaskMutex. You can then either use a synchronized class, or use the lock idiom (basically casts away shared in a safe way). setSameMutex is in object.d and I think the argument order must be setSameMutex(object, task_mutex); but I'm not sure.