Jump to page: 1 2
Thread overview
To copy an auto class
Jun 08, 2004
Arcane Jill
Jun 09, 2004
Walter
Jun 09, 2004
Arcane Jill
Jun 09, 2004
Walter
Jun 09, 2004
Arcane Jill
Jun 09, 2004
Walter
Jun 10, 2004
Russ Lewis
Jun 10, 2004
Arcane Jill
Jun 10, 2004
Russ Lewis
Jun 10, 2004
Arcane Jill
Jun 10, 2004
Russ Lewis
Jun 11, 2004
Roberto Mariottini
Jun 11, 2004
Arcane Jill
Jun 12, 2004
Matthew
June 08, 2004
Auto classes would be a lot more useful if you could copy them. Now, I *do* understand the issues here. I've written a lot of explicit memory management stuff in C++. Basically, you need a C++-style copy-constructor.

That is, when copying an auto variable from one place to another, you must ensure that a specially written function (copy constructor) is called in which the resource is explicitly reference-counted. The destructor releases the resource only when the number of explicitly counted references reaches zero. This allows you to pass auto variables to functions, and to receive them as return values from functions.

This sort of thing can be tedious to write - but sometimes it's the only way to get the job done.

..but that's in C++. In D - well, you can't do it AT ALL.

So, what with auto classes not allowing copying, lazy destruction causing the non-auto destructors not to run, and class deallocators apparently being just as lazy as destructors, it would appear that there is NO WAY to manage a resource that you want to be able to copy.

Short of writing my own garbage collector, that is. (And freeing module
resources at module unload time using static ~this() is an even worse solution).

I require a mechanism which will guarantee destruction of a copyable object. There must be a way for D to provide this. I suggest either:

(1) an attribute which will cause a class's destructor to run when the gc
decides it is time to do so (that is, which requires the gc not to be lazy about
this class.
(2) a guarantee that class deallocators will always be run, or
(3) to allow an auto class to be copied if it has a copy constructor. (I'd even
be happy if the compiler required a special keyword such as
dont_blame_me_if_it_crashes, to put off the unwary).

I hope someone has the heart to do something about this. Arcane Jill


June 09, 2004
"Arcane Jill" <Arcane_member@pathlink.com> wrote in message news:ca5i7n$71o$1@digitaldaemon.com...
> Auto classes would be a lot more useful if you could copy them. Now, I
*do*
> understand the issues here. I've written a lot of explicit memory
management
> stuff in C++. Basically, you need a C++-style copy-constructor.
>
> That is, when copying an auto variable from one place to another, you must ensure that a specially written function (copy constructor) is called in
which
> the resource is explicitly reference-counted. The destructor releases the resource only when the number of explicitly counted references reaches
zero.
> This allows you to pass auto variables to functions, and to receive them
as
> return values from functions.
>
> This sort of thing can be tedious to write - but sometimes it's the only
way to
> get the job done.
>
> ..but that's in C++. In D - well, you can't do it AT ALL.
>
> So, what with auto classes not allowing copying, lazy destruction causing
the
> non-auto destructors not to run, and class deallocators apparently being
just as
> lazy as destructors, it would appear that there is NO WAY to manage a
resource
> that you want to be able to copy.
>
> Short of writing my own garbage collector, that is. (And freeing module
> resources at module unload time using static ~this() is an even worse
solution).
>
> I require a mechanism which will guarantee destruction of a copyable
object.
> There must be a way for D to provide this. I suggest either:
>
> (1) an attribute which will cause a class's destructor to run when the gc
> decides it is time to do so (that is, which requires the gc not to be lazy
about
> this class.
> (2) a guarantee that class deallocators will always be run, or
> (3) to allow an auto class to be copied if it has a copy constructor. (I'd
even
> be happy if the compiler required a special keyword such as dont_blame_me_if_it_crashes, to put off the unwary).
>
> I hope someone has the heart to do something about this. Arcane Jill

There is a misunderstanding here, as the gc *will* call the destructor when an object is collected. What it doesn't do is guarantee that all objects will be collected, since some random bit pattern may hold on to it.

Next, if one really does need reference counting, just use the AddRef() and
Release() protocol used with traditional COM programming. It works, it's
just not automatic.


June 09, 2004
In article <ca69nd$186h$1@digitaldaemon.com>, Walter says...

>There is a misunderstanding here, as the gc *will* call the destructor when an object is collected. What it doesn't do is guarantee that all objects will be collected, since some random bit pattern may hold on to it.

Then the question remains. If I cannot guarantee that a non-auto class will not be collected, the problem has not gone away.

Either I make a class auto - in which case it (currently) cannont be copied, or
I make a class non-auto, in which case it (currently) will not necessarily be
properly destroyed.

I require a class which I can copy, and for which I can absolutely guarantee destruction. It needs to exist in an application such a server (for which module unload may not happen for months at a time, if at all). My experiments (see separate post) reveal that non-auto objects are quite definitely not always destroyed, so - how do I solve this dilemma? If I have to go so far as writing my own parallel garbage collector, that may be a step too far.



>Next, if one really does need reference counting, just use the AddRef() and
>Release() protocol used with traditional COM programming. It works, it's
>just not automatic.

I am writing a security application Walter. It *MUST* be automatic. I will go so far as to lock the data in memory to prevent it from being written to a swap file. I will go so far as to request notification from the operating system before the system hibernates for the same reason. I'm not messing about here.

I require that *EITHER* a destructor is guaranteed to be called, *OR* that a custom deallocator is guaranteed to be called, *AND* that such objects may be copied.

If you make auto classes copyable, then, believe it or not, that will actually solve the problem. Right now, auto classes are useless for all but the simplest of RAII techniques.

Jill


June 09, 2004
"Arcane Jill" <Arcane_member@pathlink.com> wrote in message news:ca6tvq$26b9$1@digitaldaemon.com...
> In article <ca69nd$186h$1@digitaldaemon.com>, Walter says...
> >There is a misunderstanding here, as the gc *will* call the destructor
when
> >an object is collected. What it doesn't do is guarantee that all objects will be collected, since some random bit pattern may hold on to it.
> Then the question remains. If I cannot guarantee that a non-auto class
will not
> be collected, the problem has not gone away.
>
> Either I make a class auto - in which case it (currently) cannont be
copied, or
> I make a class non-auto, in which case it (currently) will not necessarily
be
> properly destroyed.
>
> I require a class which I can copy, and for which I can absolutely
guarantee
> destruction. It needs to exist in an application such a server (for which
module
> unload may not happen for months at a time, if at all). My experiments
(see
> separate post) reveal that non-auto objects are quite definitely not
always
> destroyed, so - how do I solve this dilemma? If I have to go so far as
writing
> my own parallel garbage collector, that may be a step too far.

Are there any 'sync' points in your app where you know that all outstanding security objects can be cleaned up?

> >Next, if one really does need reference counting, just use the AddRef()
and
> >Release() protocol used with traditional COM programming. It works, it's
> >just not automatic.
>
> I am writing a security application Walter. It *MUST* be automatic. I will
go so
> far as to lock the data in memory to prevent it from being written to a
swap
> file. I will go so far as to request notification from the operating
system
> before the system hibernates for the same reason. I'm not messing about
here.

I'm misunderstanding you. If you're writing it, you can completely control
the AddRef() and Release() functionality, although the compiler won't do it
for you.

> I require that *EITHER* a destructor is guaranteed to be called, *OR* that
a
> custom deallocator is guaranteed to be called, *AND* that such objects may
be
> copied.

Do you mean copy the contents of the object, or copy a reference to it?

> If you make auto classes copyable, then, believe it or not, that will
actually
> solve the problem. Right now, auto classes are useless for all but the
simplest
> of RAII techniques.


June 09, 2004
In article <ca7m1d$a47$3@digitaldaemon.com>, Walter says...

>Are there any 'sync' points in your app where you know that all outstanding security objects can be cleaned up?

You can relax now. Ben Hinkle has completely ended my misunderstanding.

But to answer your question, for any application that I write, yes, I can do that. However, if I just supply a library and OTHER PEOPLE write apps using it, then obviously I can't. But like I said, it doesn't matter now.


>Do you mean copy the contents of the [auto] object, or copy a reference to it?

Well, it's complicated. I meant copy a reference to it. BUT - we're talking RAII classes here, and, as you know, multiple references to the same RAII object cause BIG problems unless you know what you're doing. However - some of us do know what we're doing and are able to manage that complexity, or at least, we could, if the compiler would let us. It would be necessary, when copying a RAII reference, to call some function within the referenced class to "do the right thing" in managing the resource. In C++, that mechanism is the following overload:

>   const T & operator=(const T &);

I /totally/ understand why you forbid this. It's the same reason that Java forbids pointers - they're dangerous, people might get it wrong, do the wrong thing and screw up badly. But if D is supposed to let us work under the hood, then maybe, just maybe, you could allow the copying of auto references providing some suitable resource management function was present in the class, and a claas writer knew what they were doing. Just a callback which notified the class that a reference to it was being copied would do the trick.

But if you don't want to allow this level of fine control, then, fair enough.

Jill


June 09, 2004
"Arcane Jill" <Arcane_member@pathlink.com> wrote in message news:ca7nb2$chc$1@digitaldaemon.com...
> I /totally/ understand why you forbid this. It's the same reason that Java forbids pointers - they're dangerous, people might get it wrong, do the
wrong
> thing and screw up badly. But if D is supposed to let us work under the
hood,
> then maybe, just maybe, you could allow the copying of auto references
providing
> some suitable resource management function was present in the class, and a
claas
> writer knew what they were doing. Just a callback which notified the class
that
> a reference to it was being copied would do the trick.
>
> But if you don't want to allow this level of fine control, then, fair
enough.

I think I understand the problem. Let me thing about it for a while. Sometimes, if I let things percolate, I can come up with something (I don't think copy constructors are the right answer).


June 10, 2004
It sounds like you need reference counting, but you don't want to call AddRef() and RemoveRef() manually.  What you want is a reference counting collector. :/  How about this code?  I haven't tested it, but I believe that it is more or less what you want.  It implements refcounting, with automatic, non-lazy, guaranteed destruction, and it uses 'auto' objects to ensure that you don't forget to remove any references.

For even more security, you could declare the Handle class to be auto, forcing ALL instances of it to be auto.



class RefCountHandle(T) {
  RefCountMeta!(T) meta;

  this(T val) {
    this.meta = new RefCountMeta!(T);
    this.meta.val = val;
    this.meta.refCount = 1;
  }
  this(RefCountMeta!(T) meta) {
    this.meta = meta;
    meta.refCount++;
  }

  ~this() {
    meta.refCount--;
    if(meta.refCount == 0) {
      delete meta.val;
      delete meta;
    }
  }

  T val() { return meta.val; }
  RefCountMeta!(T) meta() { return meta; }
}

class RefCountMeta(T) {
  T val;
  int refCount;
}

void foo() {
  auto RefCountHandle!(MyClass) secureObj;
    secureObj = new RefCountHandle!(MyClass)(new MyClass)

  bar(secureObj.meta);
}
void bar(RefCountMeta!(MyClass) arg) {
  auto RefCountHandle!(MyClass) secureObj;
    secureObj = new RefCountHandle!(MyClass)(arg);
}

Walter wrote:
> "Arcane Jill" <Arcane_member@pathlink.com> wrote in message
> news:ca7nb2$chc$1@digitaldaemon.com...
> 
>>I /totally/ understand why you forbid this. It's the same reason that Java
>>forbids pointers - they're dangerous, people might get it wrong, do the
> 
> wrong
> 
>>thing and screw up badly. But if D is supposed to let us work under the
> 
> hood,
> 
>>then maybe, just maybe, you could allow the copying of auto references
> 
> providing
> 
>>some suitable resource management function was present in the class, and a
> 
> claas
> 
>>writer knew what they were doing. Just a callback which notified the class
> 
> that
> 
>>a reference to it was being copied would do the trick.
>>
>>But if you don't want to allow this level of fine control, then, fair
> 
> enough.
> 
> I think I understand the problem. Let me thing about it for a while.
> Sometimes, if I let things percolate, I can come up with something (I don't
> think copy constructors are the right answer).

June 10, 2004
In article <ca8uhv$282p$1@digitaldaemon.com>, Russ Lewis says... <clever stuff>

Cunning. Of course the same trick looks A LOT neater in C++ where you can overload ->. I've done that sort of thing myself, many a time (just not in D).

>    ptr<T> a;       // one of it
>    ptr<T> b = a;   // two of it
>    a->f();         // calls T::f() for the instance a

But D's template syntax is a little more cumbersome, and you can't overload ->.

Arcane Jill


June 10, 2004
Doesn't this just imply that 'auto' should instead be 'refcount'?  If the compiler implemented refcounting on specially marked variables, then this would be easy...

June 10, 2004
In article <caabq3$1gpe$1@digitaldaemon.com>, Russ Lewis says...
>
>Doesn't this just imply that 'auto' should instead be 'refcount'?

No, I'm afraid it's not going to be that simple. The reason that you can't (currently) copy an auto class reference is because it's a very dangerous thing to do. If you're going to do it at all (if Walter lets us), you have to know exactly what you're doing. The compiler won't do reference counting for you. IF that's the appropriate thing to do with a given RAII resource (and it might not be), then you'll have to do it yourself, the hard way.


>If the compiler implemented refcounting on specially marked variables, then this would be easy...

If only. Alas, no compiler can be a mind-reader. :)

For non-auto classes of course, we don't need reference counting anyway. The normal behavior of the garbage collected does the same thing only better.

Jill


« First   ‹ Prev
1 2