gnash-dev
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Gnash-dev] Re: Garbage Collection


From: strk
Subject: Re: [Gnash-dev] Re: Garbage Collection
Date: Thu, 20 Sep 2007 13:25:40 +0200

On Thu, Sep 20, 2007 at 05:08:17PM +0900, Chad Musick wrote:

> Or this, which uses the auto_ptr:
> void doSomething3()
> {
>         GcInvoke myInvoke(false); // manually managed
>         std::auto_ptr<SomeGcClass> p(new SomeGcClass);
>         if (p->do_something())
>         {
>                 member = p.release();
>                 GC::manage(p); // Now Gc managed.
>         }
> }
> (This example made me change the 'manage' function in the GC to use
> GcInvoke, since I realized that the problems of doSomething1()
> doSomething2() make it unsafe for 'manage' to immediately cause
> management -- I was properly handling 2), but not 1))

Would a GC::manage() call outside of GcInvoke presence cause an assertion 
failure 
or equivalent exception ?

> The Caveat --
> GcInvoke uses thread local storage, and so the 'manage' state of
> information is dependent on the thread.  Spawning a new thread and
> allocating from there isn't safe.
> Example:
> class func_obj { public: operator() { member = new GcObject; } .... };
> Assuming that func_obj properly marks all of its members and such, this
> is still not safe, because the allocation of member is not done within a
> GcInvoke scope.  Doing this:
> someFunction1() { GcInvoke myInvoke; boost::thread T(func_obj()); }
> does not make it safe -- the func_obj cannot benefit from the GcInvoke.
> This is bad practice anyway.

Alright, the example above is bad becuase operator() is allocating w/out 
stack-allocating
a GcInvoke, right ? Would a GcInvoke in operator() make the latter safe ?

 class func_obj { public: operator() { GcInvoke myInvoke; member = new 
GcObject; } .... };
 someFunction1() { GcInvoke myInvoke; boost::thread T(func_obj()); }

> Not changing structure --
> 
> This is okay, without a need to lock:
> std::list<GcObject*> myList;
> std::list<GcObject*>::iterator i = myList.find("something");
> *i = new GcObject;
> // Because this does not modify the structure -- ie. does not invalidate
> any iterators of the list, this is okay.
> 
> This is not okay, unless you lock:
> std::list<GcObject*> myList;
> std::list<GcObject*>::iterator i = myList.find("something");
> myList.erase(i);
> // This invalidates i, so the list must be locked to do this.
> 
> The reason is that the GC uses the iterators to mark containers and
> invalidating the iterators may make the Gc de-reference or increment an
> invalid iterator.

This makes me think a GcManagedContainer class would be appropriate here,
to be used whenever the container contains GC-managed objects.
The class could take care of proper locking, what do you think ?

--strk;




reply via email to

[Prev in Thread] Current Thread [Next in Thread]