On Sunday, 12 June 2016 at 14:49:18 UTC, Gary Willoughby wrote:
Hmmm. I thought it looked *too* simple. Have you any idea if there is a simple solution to this?

yes. you have to turn your refcount to pointer. ;-)

the cause of "misbehave" is the fact that there can exist several copies of the struct made in different program points, and they all have *independent* refcounter. but all those copies should have the *same* refcounter. the easiest way to solve this is to allocate refcounter separately, and only share *pointer* to it, like this:

struct Foo {
  int* refcount;

  void allocResources () {
    import core.stdc.stdlib : malloc;
    assert(refcount is null);
    refcount = cast(int*)malloc(int.size);
    *refcount = 1;
    // init other resources
  }

  this (this) { if (refcount !is null) *refcount += 1; }

// we need to do this in opAssign() and in dtor, hence the function
  private void decRef () {
    if (refcount !is null) {
      if ((*refcount -= 1) == 0) {
        import core.stdc.stdlib : free;
        free(refcount);
        // free resources
      }
    }
  }

  ~this (this) { decRef(); }

  // yes, we need this too
  void opAssign (Foo src) {
*src.refcount += 1; // it is important to increase it first, in case `src` and `this` are sharing refcount
    decRef(); // release our resources
    *refcount = *src.refcount;
    // copy other handles and so on
  }
}


this is basically how refcounted structs are done. note that i just typed the code into reply box, so it may not compile or contain some small bugs, but i think you got the idea.

Reply via email to