set_weak_flag() for objects?

classic Classic list List threaded Threaded
9 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

set_weak_flag() for objects?

Stephen R. van den Berg
What if I have an object like this:

class Server {
  private mixed id;

  void create() {
    id = this;
    werror("Created\n");
  }

  void destroy() {
    werror("Destructed\n");
  }
}

object ref = Server();
ref = 0; // At this point, I want the object to "selfdestruct"

But the selfdestruct doesn't work because of the internal reference from id
to the class instance.
How can I mark the member id as a weak reference?
--
Stephen.

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: set_weak_flag() for objects?

Stephen R. van den Berg
Tried some more, not even the workarounds work as expected:

class NoRef {
  void create() {
    werror("Created NoRef\n");
  }

  void destroy() {
    werror("Destructed NoRef\n");
  }
}

class Ref {
  private mixed id;

  void create() {
    id = this;
    werror("Created Ref\n");
  }

  void destroy() {
    werror("Destructed Ref\n");
  }
}

class WRef {
  private array id;

  void create() {
    id = ({0});
    set_weak_flag(id, Pike.WEAK);
    id[0] = this;
    set_weak_flag(id, Pike.WEAK);
    werror("Created WRef %O\n", get_weak_flag(id));
  }

  void destroy() {
    werror("Destructed WRef\n");
  }
}

int main(int argc, array(string) argv) {
  object a;
  a = WRef(); a = 0;
  a = NoRef(); a = 0;
  a = Ref(); a = 0;
  werror("Finished\n");
  return 0;
}

Any ideas?
--
Stephen.

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: set_weak_flag() for objects?

Arne Goedeke
Weak references are resolved (i.e. objects which only have weak
references are destructed) only if 1) the gc runs or 2) when a mapping
is rehashed. This means that in your example the object is only
destructed when the gc runs. In your situation I would recommend doing
something like this:

class FOO {
        private mixed _id;
       
        mixed `id() {
                return _id || this;
        }
}

Hope that helps.

Arne

On 09/21/16 12:14, Stephen R. van den Berg wrote:

> Tried some more, not even the workarounds work as expected:
>
> class NoRef {
>   void create() {
>     werror("Created NoRef\n");
>   }
>
>   void destroy() {
>     werror("Destructed NoRef\n");
>   }
> }
>
> class Ref {
>   private mixed id;
>
>   void create() {
>     id = this;
>     werror("Created Ref\n");
>   }
>
>   void destroy() {
>     werror("Destructed Ref\n");
>   }
> }
>
> class WRef {
>   private array id;
>
>   void create() {
>     id = ({0});
>     set_weak_flag(id, Pike.WEAK);
>     id[0] = this;
>     set_weak_flag(id, Pike.WEAK);
>     werror("Created WRef %O\n", get_weak_flag(id));
>   }
>
>   void destroy() {
>     werror("Destructed WRef\n");
>   }
> }
>
> int main(int argc, array(string) argv) {
>   object a;
>   a = WRef(); a = 0;
>   a = NoRef(); a = 0;
>   a = Ref(); a = 0;
>   werror("Finished\n");
>   return 0;
> }
>
> Any ideas?
>

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: set_weak_flag() for objects?

Stephen R. van den Berg
Arne Goedeke wrote:
>Weak references are resolved (i.e. objects which only have weak
>references are destructed) only if 1) the gc runs or 2) when a mapping
>is rehashed. This means that in your example the object is only
>destructed when the gc runs. In your situation I would recommend doing
>something like this:

I see.  So because objects only have a reference counter, and not both a
normal and a weak reference counter, it's impractical to trigger an
autodestruct when there are only weak references left.

>class FOO {
> private mixed _id;

> mixed `id() {
> return _id || this;

Well, that would solve it, a bit, at some extra CPU expense, but since
people are likely to set id to an array which in turn might include
a reference to "this" again, it won't solve the essential problem.
I'll revert to destruct()ing instead.
--
Stephen.

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: set_weak_flag() for objects?

Arne Goedeke
Maybe in that case a different API makes more sence, for instance by
always passing this and any extra arguments. This would at least deter
users from accidentally creating additional cycles, which can lead to
long GC pauses. Not sure what the priorities are of course.

arne

On 09/21/16 12:58, Stephen R. van den Berg wrote:

> Arne Goedeke wrote:
>> Weak references are resolved (i.e. objects which only have weak
>> references are destructed) only if 1) the gc runs or 2) when a mapping
>> is rehashed. This means that in your example the object is only
>> destructed when the gc runs. In your situation I would recommend doing
>> something like this:
>
> I see.  So because objects only have a reference counter, and not both a
> normal and a weak reference counter, it's impractical to trigger an
> autodestruct when there are only weak references left.
>
>> class FOO {
>> private mixed _id;
>
>> mixed `id() {
>> return _id || this;
>
> Well, that would solve it, a bit, at some extra CPU expense, but since
> people are likely to set id to an array which in turn might include
> a reference to "this" again, it won't solve the essential problem.
> I'll revert to destruct()ing instead.
>

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: set_weak_flag() for objects?

Stephen R. van den Berg
Arne Goedeke wrote:
>Maybe in that case a different API makes more sence, for instance by
>always passing this and any extra arguments. This would at least deter

In this case it's not that tragic.
The objects are "connected" to the network sessions.
You either terminate them manually, in which case I clear out the id
variable just in case, so it autodestructs, or the object will autoterminate
when the connection closes.

Just dropping all references to the object won't kill it, the callbacks will
still be called.
Unless someone educates me otherwise, I think this is just fine, because
the typical use cases operate on read and close callbacks only, the object
itself is not interesting.
--
Stephen.

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: set_weak_flag() for objects?

Henrik Grubbström-2
In reply to this post by Arne Goedeke
On Wed, 21 Sep 2016, Arne Goedeke wrote:

> Weak references are resolved (i.e. objects which only have weak
> references are destructed) only if 1) the gc runs or 2) when a mapping
> is rehashed. This means that in your example the object is only
> destructed when the gc runs. In your situation I would recommend doing
> something like this:
>
> class FOO {
> private mixed _id;
>
> mixed `id() {
> return _id || this;
> }
> }
NB: There's a special case in the reference counting for variables
in objects of classes written in pure Pike, where direct circular
references aren't counted (cf PIKE_T_NO_REF_*), so the above
construction isn't strictly needed (but still recommended).

  /grubba

--
Henrik Grubbström [hidden email]
Roxen Internet Software AB
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: set_weak_flag() for objects?

Stephen R. van den Berg
Henrik Grubbstr?m wrote:
>NB: There's a special case in the reference counting for variables
>in objects of classes written in pure Pike, where direct circular
>references aren't counted (cf PIKE_T_NO_REF_*), so the above
>construction isn't strictly needed (but still recommended).

Then why does my simple self-referencing example class not autodestruct?
--
Stephen.

Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: set_weak_flag() for objects?

Henrik Grubbström-2
On Wed, 21 Sep 2016, Stephen R. van den Berg wrote:

> Henrik Grubbstr?m wrote:
>> NB: There's a special case in the reference counting for variables
>> in objects of classes written in pure Pike, where direct circular
>> references aren't counted (cf PIKE_T_NO_REF_*), so the above
>> construction isn't strictly needed (but still recommended).
>
> Then why does my simple self-referencing example class not autodestruct?

Oops, my fault; it was only activated for variables declared as object or
as function.

Fixed for mixed in Pike 8.0 and 8.1.

--
Henrik Grubbström [hidden email]
Roxen Internet Software AB
Loading...