Login
Username:

Password:

Remember me



Lost Password?

Register now!

Sections

Who's Online
171 user(s) are online (156 user(s) are browsing Forums)

Members: 1
Guests: 170

billyfish, more...

Support us!

Headlines

 
  Register To Post  

Completely detached process
Supreme Council
Supreme Council


See User information
I'm trying to create a process from my program using CreateNewProcTags().

It works just fine until I exit the main program before exiting the process. I get a grimreaper inside DOS.library. Exiting the process before the program and it all works just fine.

This is the code I use for creating my process:

IDOS->CreateNewProcTags(NP_EntryProcInformation_child,
                         
NP_Name"ProcInformation",
                         
NP_LocalVars,vars,
                         
TAG_DONE);


It seems that the process I create is still attached to the original program somehow. How do I make them completely detached from each other?

Vacca foeda. Sum, ergo edo

Mr Bobo Cornwater
Go to top
Re: Completely detached process
Just popping in
Just popping in


See User information
@orgin

If you get an ISI exception, the main program probably UnloadSeg()s code the spawned process is still executing.

Go to top
Re: Completely detached process
Supreme Council
Supreme Council


See User information
@centaurz

Hmm okey. Here's the crash log: http://crashlog.os4depot.net/?function=view&crashlogid=147

How do I get it to not do that then?

Edit:
The autodoc says:
"     If your child process is designed to persist after the parent exits,
     then DO NOT create persistent child processes that use this tag."


So I assume that it is supposed to be possible. (it's about the NP_Child tag which I'm not using)

Vacca foeda. Sum, ergo edo

Mr Bobo Cornwater
Go to top
Re: Completely detached process
Just popping in
Just popping in


See User information
@orgin

You could "transfer" the seglist ownership to the process (use NP_SegList tag with CreateNewProc), but you still have to prevent the program from freeing it itself.

Go to top
Re: Completely detached process
Supreme Council
Supreme Council


See User information
@centaurz

Is that a guess or is that how you're supposed to do it? :)

Vacca foeda. Sum, ergo edo

Mr Bobo Cornwater
Go to top
Re: Completely detached process
Just popping in
Just popping in


See User information
@orgin

It's a guess based on vague memories and Autodocs reading .
(BTW, use GetProcSegList() to obtain the seglist).

Edit: However, can't find a function to change the seglist (Colin, where are you ? )

Go to top
Re: Completely detached process
Supreme Council
Supreme Council


See User information
Anyone else? :)

Vacca foeda. Sum, ergo edo

Mr Bobo Cornwater
Go to top
Re: Completely detached process
Just can't stay away
Just can't stay away


See User information
@orgin

In order for a child process to be completely separate from its parent it needs to have it's own seglist.

This means using LoadSeg(), NP_SegList instead of NP_Entry and setting NP_FreeSegList to TRUE.

TBH I would suggest using SystemTags() with SYS_Asynch enabled instead of CreateNewProc(), since CreateNewProc() generally doesn't work so well with C startup code. For an example on how to do this you can look at the splashlauncher source code from OS4Depot.

Centaurz's suggestion won't work since there is no reference counter inside seglist so you can't make the OS free the seglist only after the last process using it has ended (this could be either parent or child).

Go to top
Re: Completely detached process
Supreme Council
Supreme Council


See User information
@salass00

Rigo explained to me that it's probably due to using newlib. The newlib base is deallcoated by the parent. The only way to avoid it is to use NP_Child, TRUE which isn't possible with the type of application I'm making. Seems I have to use clib2.

As for SystemTags, I'm not really interested in calling an external program.

Vacca foeda. Sum, ergo edo

Mr Bobo Cornwater
Go to top
Re: Completely detached process
Just popping in
Just popping in


See User information
The subprocess is still running in the code space loaded for the parent.
The parent exits, unloads the code, subprocess crashes.
That's pretty well outlines your problem.

Two basic ways to fix this....

1) Use NP_Child tag and make the parent Wait()/WaitMsg()
until the child exits, see; NP_NotifyOnDeathMessage and NP_NotifyOnDeathSigTask.
Set up a message/signal and only allow the parent to leave only when the child notifies you of its death.
However, this means that the parent must go to sleep until the child exits, which means that if
the parent was a shell process, the CLI will be "dead" until the child ends.

2) If you wish to affect a complete detachment of the child and allow the parent to completely exit
while allowing the child to continue execution in the old code space, then the resources that are
shared by the child MUST also be detached.

This can be a little more complicated and not really for the beginner.
Nevertheless, here's an outline of what needs to be done.


The easiest way is to call CreateNewProc() with no tags for the NP_Input,NP_Output,NP_Error,
these will then open a default "NIL:" stream for the child (and 0 for the error stream).
(and with NP_Child,FALSE)

With that taken care of, (here's the tricky part), because as the seglist is being shared,
you must make sure it is not freed by the parent process on exit,

You can transfer ownership to the child process, so that it frees it on exit instead,
so it is not done by the parent.
To do this, you need to determine who loaded the original, this can be the shell or 'other'.
If the shell loaded it, you need to stop it from unloading the command on exit.

Here's some pseudocode.....

============

BPTR seg = ZERO;
struct CommandLineInterface *cli = IDOS->Cli();
if( cli )
{
seg = cli->cli_Module;
cli->cli_Module = ZERO; /* stop shell freeing the seg */
}
else /* not a cli, try 'other' load methods */
{
seg = IDOS->GetProcSegList(NULL,GPSLF_SEG);
if( seg )
{
struct Process *me = (struct Process *)FindTask(0);
me->pr_Flags &= (~PRF_FREESEGLIST);
} /* clear the flag for parent to free seglist */
}


if( seg ) /* did we find a loadsegged seglist ? */
{
IDOS->CreateNewProcTags(
NP_Entry, child_entry_func, /* entry() here */
NP_SegList, seg, /* free this seg on exit */
NP_FreeSegList,TRUE, /* make it so */
...
TAG_END);

}
else
{
PutStr("ERROR: Cannot find loaded seglist..\n");
}


NOTE WELL:
You cannot call newlib functions in the child process unless you re-open the library within
the child process itself, and set the childProc->pr_CLibData to the newlib base as there will
be no default library context available to the child.

Better to just use the IDOS-> functions while inside the child process.


Also note that as the child is now responsible for freeing the seglist on exit, you MUST make sure the parent now exits BEFORE the child does, otherwise you will find yourself in the same situation.

Go to top
Re: Completely detached process
Supreme Council
Supreme Council


See User information
@colinw

Unfortunately I need to be able to create an arbitrary amount of processes with no prior knowledge as to which process termination that should deallocate the seglist.

It would have been better for the OS to keep track of each seglist subscriber using a reference counter and not actually deallocate it until there's no subscriber left (As salass00 suggested). I'm surprised that the OS doesn't already do this when it permits creating processes (NP_Entry+NP_Child,FALSE) that shares the seglist.

Ohh well, perhaps something for OS4.2? ;)

Vacca foeda. Sum, ergo edo

Mr Bobo Cornwater
Go to top
Re: Completely detached process
Just popping in
Just popping in


See User information
@orgin


Seeing you can see the problem area ahead of you,
then make it so EVERY child can deallocate the seglist,
by creating the children with the same seglist tag,
but set the NP_FreeSegList,FALSE on child creation.

Then, use ProcessScan() at the exit point of the common
child code to find out how many of your child processes
are still running, and when the last one is exiting
(ie; only 1 child) then delegate that child to be the
process that frees the seglist by setting its
proc->pr_Flags |= PRF_FREESEGLIST; bit,
then simply return() to DOS.

There is example code in the ProcessScan() autodoc.
See the "SignalMyChildProcsToExit" example code and
just lose the Signal(), and use any of the child procs
pr_ParentID to scan for other descendants, it will return
the child process count.

Just beware of handlers being started up, therefore use
a second tier check, i'd suggest a magic cookie in
NP_UserData, or NP_EntryData or NP_ExitData or such,
when starting the actual child processes.

Enjoy...

Go to top

  Register To Post

 




Currently Active Users Viewing This Thread: 1 ( 0 members and 1 Anonymous Users )




Powered by XOOPS 2.0 © 2001-2024 The XOOPS Project