Jump to page: 1 2
Thread overview
new thread with nested function
Apr 06, 2005
bobef
Apr 07, 2005
Regan Heath
Apr 07, 2005
bobef
Apr 07, 2005
Ben Hinkle
Apr 07, 2005
Regan Heath
Apr 07, 2005
Regan Heath
Apr 07, 2005
Russ Lewis
Apr 07, 2005
Regan Heath
Apr 07, 2005
Russ Lewis
Apr 08, 2005
Regan Heath
Apr 07, 2005
Sean Kelly
Apr 08, 2005
Regan Heath
Apr 07, 2005
Sean Kelly
Apr 07, 2005
David Medlock
Apr 07, 2005
Sean Kelly
Apr 07, 2005
Russ Lewis
April 06, 2005
I don't know if this is a bug so I post it here. If new thread is started with nested function as delegate it sees it's parents variables and class variables (if parent is class member) but they are all 'dead'...


April 07, 2005
On Wed, 6 Apr 2005 20:58:28 +0000 (UTC), bobef <bobef_member@pathlink.com> wrote:
> I don't know if this is a bug so I post it here. If new thread is started with
> nested function as delegate it sees it's parents variables and class variables
> (if parent is class member) but they are all 'dead'...

Do you exit the parent function after starting the thread?
What is meant by "dead" exactly?

Regan
April 07, 2005
Yes I exit the parent function. And by 'dead' I mean I do not get compiler errors but memory contained in these vairables is unsusable (corrupted, moved or deallocated or something like that). I suppose parent's variables are released when it gets out of scope or something like that but I think then it should be forbidden to pass nested functions as parameters for threads or something like that...

In article <opsoufcrkw23k2f5@nrage.netwin.co.nz>, Regan Heath says...
>
>On Wed, 6 Apr 2005 20:58:28 +0000 (UTC), bobef <bobef_member@pathlink.com> wrote:
>> I don't know if this is a bug so I post it here. If new thread is
>> started with
>> nested function as delegate it sees it's parents variables and class
>> variables
>> (if parent is class member) but they are all 'dead'...
>
>Do you exit the parent function after starting the thread? What is meant by "dead" exactly?
>
>Regan


April 07, 2005
"bobef" <bobef_member@pathlink.com> wrote in message news:d33574$1s6j$1@digitaldaemon.com...
> Yes I exit the parent function. And by 'dead' I mean I do not get compiler
> errors but memory contained in these vairables is unsusable (corrupted,
> moved or
> deallocated or something like that). I suppose parent's variables are
> released
> when it gets out of scope or something like that but I think then it
> should be
> forbidden to pass nested functions as parameters for threads or something
> like
> that...

Disallowing passing nested functions would be pretty harsh. It would be like disallowing passing pointers to local variables to functions because the pointers could be held onto and dereferenced after the local variable is no longer valid. If the documentation on threading or nested functions could include a little blurb about the dangers of passing nested functions to threads (or for that matter doing anything that runs a nested function after the stack is gone).


April 07, 2005
On Thu, 7 Apr 2005 11:23:16 +0000 (UTC), bobef <bobef_member@pathlink.com> wrote:
> Yes I exit the parent function. And by 'dead' I mean I do not get compiler
> errors but memory contained in these vairables is unsusable (corrupted, moved or
> deallocated or something like that). I suppose parent's variables are released
> when it gets out of scope or something like that

I suspect that's exactly what is happening.

> but I think then it should be
> forbidden to pass nested functions as parameters for threads or something like
> that...

I'm with Ben on this one.
Here is an example highlighting the issue:
(windows only, sorry linux guys)

import std.c.windows.windows;
import std.stdio;
import std.thread;
import std.stream;

struct stest
{
	int a = 5;
	
	int run()
	{
		writefln("s",a);
		Sleep(1000);
		writefln("s",a);
		Sleep(1000);
		writefln("s",a);
	}
}

class ctest
{
	int a = 6;
	
	int run()
	{
		writefln("c",a);
		Sleep(1000);
		writefln("c",a);
		Sleep(1000);
		writefln("c",a);
	}
}

void main()
{
	fire();
	Sleep(10000);	
}
void fire()
{
	Thread t;
	ctest b = new ctest();
	stest a;
	
	t = new Thread(&a.run);
	t.start();
	
	t = new Thread(&b.run);
	t.start();
	
	Sleep(1000);
}

Regan
April 07, 2005
I forgot to mention. This example was actually my test to see what happens with structs vs classes. What I was trying to answer was:

1. does passing a struct delegate to a thread stop the struct from being free'd.
2. does passing a class delegate to a thread stop the class from being free'd.

The answer to #1 seems to be no. No surprises really, it's a value type stored on the stack, not a reference.

I wasn't sure I had answered #2, to be sure I added a fullCollect (see code below).

It appears passing a class delegate, prevents the class from being free'd, which is good, I wondered whether the delegate pointer would do that, or if it had been overlooked.

Have I overlooked something?

Regan

On Fri, 08 Apr 2005 00:40:33 +1200, Regan Heath <regan@netwin.co.nz> wrote:
> Here is an example highlighting the issue:
> (windows only, sorry linux guys)
>
> import std.c.windows.windows;
> import std.stdio;
> import std.thread;
> import std.stream;
>
> struct stest
> {
> 	int a = 5;
> 	
> 	int run()
> 	{
> 		writefln("s",a);
> 		Sleep(1000);
> 		writefln("s",a);
> 		Sleep(1000);
> 		writefln("s",a);
> 	}
> }
>
> class ctest
> {
> 	int a = 6;
> 	
> 	int run()
> 	{
> 		writefln("c",a);
> 		Sleep(1000);
> 		writefln("c",a);
> 		Sleep(1000);
> 		writefln("c",a);
> 	}
> }
>
> void main()
> {
> 	fire();
 	Sleep(1000);
	fullCollect();	
> 	Sleep(10000);
> }
> void fire()
> {
> 	Thread t;
> 	ctest b = new ctest();
> 	stest a;
> 	
> 	t = new Thread(&a.run);
> 	t.start();
> 	
> 	t = new Thread(&b.run);
> 	t.start();
> 	
> 	Sleep(1000);
> }
>
> Regan

April 07, 2005
If you allocated the struct on the stack, then it should not be GC'd until the delegate goes away.

Regan Heath wrote:
> I forgot to mention. This example was actually my test to see what happens  with structs vs classes. What I was trying to answer was:
> 
> 1. does passing a struct delegate to a thread stop the struct from being  free'd.
> 2. does passing a class delegate to a thread stop the class from being  free'd.
> 
> The answer to #1 seems to be no. No surprises really, it's a value type  stored on the stack, not a reference.
> 
> I wasn't sure I had answered #2, to be sure I added a fullCollect (see  code below).
> 
> It appears passing a class delegate, prevents the class from being free'd,  which is good, I wondered whether the delegate pointer would do that, or  if it had been overlooked.
> 
> Have I overlooked something?
> 
> Regan
> 
> On Fri, 08 Apr 2005 00:40:33 +1200, Regan Heath <regan@netwin.co.nz> wrote:
> 
>> Here is an example highlighting the issue:
>> (windows only, sorry linux guys)
>>
>> import std.c.windows.windows;
>> import std.stdio;
>> import std.thread;
>> import std.stream;
>>
>> struct stest
>> {
>>     int a = 5;
>>         int run()
>>     {
>>         writefln("s",a);
>>         Sleep(1000);
>>         writefln("s",a);
>>         Sleep(1000);
>>         writefln("s",a);
>>     }
>> }
>>
>> class ctest
>> {
>>     int a = 6;
>>         int run()
>>     {
>>         writefln("c",a);
>>         Sleep(1000);
>>         writefln("c",a);
>>         Sleep(1000);
>>         writefln("c",a);
>>     }
>> }
>>
>> void main()
>> {
>>     fire();
> 
>      Sleep(1000);
>     fullCollect();   
> 
>>     Sleep(10000);
>> }
>> void fire()
>> {
>>     Thread t;
>>     ctest b = new ctest();
>>     stest a;
>>         t = new Thread(&a.run);
>>     t.start();
>>         t = new Thread(&b.run);
>>     t.start();
>>         Sleep(1000);
>> }
>>
>> Regan
> 
> 
April 07, 2005
In article <opsou4v7p323k2f5@nrage.netwin.co.nz>, Regan Heath says...
>
>I forgot to mention. This example was actually my test to see what happens with structs vs classes. What I was trying to answer was:
>
>1. does passing a struct delegate to a thread stop the struct from being
>free'd.
>2. does passing a class delegate to a thread stop the class from being
>free'd.
>
>The answer to #1 seems to be no. No surprises really, it's a value type stored on the stack, not a reference.

Right.

>I wasn't sure I had answered #2, to be sure I added a fullCollect (see code below).
>
>It appears passing a class delegate, prevents the class from being free'd, which is good, I wondered whether the delegate pointer would do that, or if it had been overlooked.

Right.  Any GCed object won't be cleaned up until all references to it are gone. The thread these references are held in is not an issue.


Sean


April 07, 2005
On Thu, 07 Apr 2005 09:52:28 -0700, Russ Lewis <spamhole-2001-07-16@deming-os.org> wrote:
> If you allocated the struct on the stack, then it should not be GC'd until the delegate goes away.

So, you think I have found a bug below?

Regan

> Regan Heath wrote:
>> I forgot to mention. This example was actually my test to see what happens  with structs vs classes. What I was trying to answer was:
>>  1. does passing a struct delegate to a thread stop the struct from being  free'd.
>> 2. does passing a class delegate to a thread stop the class from being  free'd.
>>  The answer to #1 seems to be no. No surprises really, it's a value type  stored on the stack, not a reference.
>>  I wasn't sure I had answered #2, to be sure I added a fullCollect (see  code below).
>>  It appears passing a class delegate, prevents the class from being free'd,  which is good, I wondered whether the delegate pointer would do that, or  if it had been overlooked.
>>  Have I overlooked something?
>>  Regan
>>  On Fri, 08 Apr 2005 00:40:33 +1200, Regan Heath <regan@netwin.co.nz> wrote:
>>
>>> Here is an example highlighting the issue:
>>> (windows only, sorry linux guys)
>>>
>>> import std.c.windows.windows;
>>> import std.stdio;
>>> import std.thread;
>>> import std.stream;
>>>
>>> struct stest
>>> {
>>>     int a = 5;
>>>         int run()
>>>     {
>>>         writefln("s",a);
>>>         Sleep(1000);
>>>         writefln("s",a);
>>>         Sleep(1000);
>>>         writefln("s",a);
>>>     }
>>> }
>>>
>>> class ctest
>>> {
>>>     int a = 6;
>>>         int run()
>>>     {
>>>         writefln("c",a);
>>>         Sleep(1000);
>>>         writefln("c",a);
>>>         Sleep(1000);
>>>         writefln("c",a);
>>>     }
>>> }
>>>
>>> void main()
>>> {
>>>     fire();
>>       Sleep(1000);
>>     fullCollect();
>>>     Sleep(10000);
>>> }
>>> void fire()
>>> {
>>>     Thread t;
>>>     ctest b = new ctest();
>>>     stest a;
>>>         t = new Thread(&a.run);
>>>     t.start();
>>>         t = new Thread(&b.run);
>>>     t.start();
>>>         Sleep(1000);
>>> }
>>>
>>> Regan
>>

April 07, 2005
EEK!  Sorry, I mistyped.  What I meant to say was that you allocate it on the *HEAP*, then it should not be GC'd until the delegate goes away.  Structs on the stack definitely *do* become invalid the moment that you return from the function.

Regan Heath wrote:
> On Thu, 07 Apr 2005 09:52:28 -0700, Russ Lewis  <spamhole-2001-07-16@deming-os.org> wrote:
> 
>> If you allocated the struct on the stack, then it should not be GC'd  until the delegate goes away.
> 
> 
> So, you think I have found a bug below?
> 
> Regan
> 
>> Regan Heath wrote:
>>
>>> I forgot to mention. This example was actually my test to see what  happens  with structs vs classes. What I was trying to answer was:
>>>  1. does passing a struct delegate to a thread stop the struct from  being  free'd.
>>> 2. does passing a class delegate to a thread stop the class from being   free'd.
>>>  The answer to #1 seems to be no. No surprises really, it's a value  type  stored on the stack, not a reference.
>>>  I wasn't sure I had answered #2, to be sure I added a fullCollect  (see  code below).
>>>  It appears passing a class delegate, prevents the class from being  free'd,  which is good, I wondered whether the delegate pointer would  do that, or  if it had been overlooked.
>>>  Have I overlooked something?
>>>  Regan
>>>  On Fri, 08 Apr 2005 00:40:33 +1200, Regan Heath <regan@netwin.co.nz>  wrote:
>>>
>>>> Here is an example highlighting the issue:
>>>> (windows only, sorry linux guys)
>>>>
>>>> import std.c.windows.windows;
>>>> import std.stdio;
>>>> import std.thread;
>>>> import std.stream;
>>>>
>>>> struct stest
>>>> {
>>>>     int a = 5;
>>>>         int run()
>>>>     {
>>>>         writefln("s",a);
>>>>         Sleep(1000);
>>>>         writefln("s",a);
>>>>         Sleep(1000);
>>>>         writefln("s",a);
>>>>     }
>>>> }
>>>>
>>>> class ctest
>>>> {
>>>>     int a = 6;
>>>>         int run()
>>>>     {
>>>>         writefln("c",a);
>>>>         Sleep(1000);
>>>>         writefln("c",a);
>>>>         Sleep(1000);
>>>>         writefln("c",a);
>>>>     }
>>>> }
>>>>
>>>> void main()
>>>> {
>>>>     fire();
>>>
>>>       Sleep(1000);
>>>     fullCollect();
>>>
>>>>     Sleep(10000);
>>>> }
>>>> void fire()
>>>> {
>>>>     Thread t;
>>>>     ctest b = new ctest();
>>>>     stest a;
>>>>         t = new Thread(&a.run);
>>>>     t.start();
>>>>         t = new Thread(&b.run);
>>>>     t.start();
>>>>         Sleep(1000);
>>>> }
>>>>
>>>> Regan
>>>
>>>
> 
« First   ‹ Prev
1 2