[comp.sys.amiga.tech] CreateNewProc

kent@swrinde.nde.swri.edu (Kent D. Polk) (12/29/90)

Please excuse my ignorance here:

If I were to start a thread from a function in my code segment using
CreateNewProc(), can I access variables global to the parent process?
Or would this thread be a full-blown process for which I would need to
set up a shared mem arrangement? The reason for this thread is to
handle gadget input events for a window created by the parent since the
parent is too busy to deal with them in a timely manner. I see I can
pass the window ptr in the CreateNewProc() call. Is this kosher?

Also, I assume I need to set up a message port in the parent process to
send a 'kill' message.  Since this thread will be used to handle all
window input events for this window (created by the parent), the window
message port should be adequate for receiving the 'kill' message, no?

I.e., am I on the right track?

Thanks much
Kent Polk: Southwest Research Institute (512) 522-2882
Internet : kent@swrinde.nde.swri.edu
UUCP     : $ {cs.utexas.edu, gatech!petro, sun!texsun}!swrinde!kent

a447@mindlink.UUCP (Colin Fox) (12/29/90)

>(kent@swrinde.nde.swri.edu) writes:
>
>Please excuse my ignorance here:

No apology necessary. :)

>If I were to start a thread from a function in my code segment using
>CreateNewProc(), can I access variables global to the parent process?
>Or would this thread be a full-blown process for which I would need to
>set up a shared mem arrangement?


The  Amiga  doesn't  distinguish  between  'threads'  and 'processes'.
Everything  is either a task or a process, and DOS is the only part of
the  system  that  cares  about  the distinction.  A process is just a
super-class  of  a  task.  So each running process/task is fully blown
and independant.


>The  reason  for  this  thread  is to handle gadget input events for a
>window created by the parent since the parent is too busy to deal with
>them  in  a  timely  manner.   I  see I can pass the window ptr in the
>CreateNewProc() call.  Is this kosher?


Hmmm  -  I  think  you're  doing this the hard way.  Why not allow the
thread  to  open  the window and manage it?  It sounds like you want a
client-server  model  here,  which  works quite well.  Trying to share
global  data  between  to  independantly  running  processes  can be a
nightmare.  Whole books are devoted to the topic.  So keep it simple.


>Also, I assume I need to set up a message port in the parent process to
>send a 'kill' message.  Since this thread will be used to handle all
>window input events for this window (created by the parent), the window
>message port should be adequate for receiving the 'kill' message, no?
>
>I.e., am I on the right track?


If  all  you  want is a single message (like KILL), then why not use a
signal?  It's simpler and incurs less overhead.

The  'window'  port  you  are talking about is for IDCMP messages, and
Intuition does things with the port and messages connected there (like
when  the  window  closes).   I wouldn't suggest you posting a private
message  at an IDCMP port.  You may inadvertently collide types with a
new one brought out by commodore.

Also, if you aren't planning on returning the message, there's no need
to  open  a  port.   You  can  send  a one-way message, as long as the
recipient knows how large it is he can delete it.


>
>Thanks much
>Kent Polk: Southwest Research Institute (512) 522-2882
>Internet : kent@swrinde.nde.swri.edu
>UUCP     : $ {cs.utexas.edu, gatech!petro, sun!texsun}!swrinde!kent
>(kent@swrinde.nde.swri.edu)

You're welcome much. Hope it helps. :)

######################################################################
#           |                             | Any opinions expressed   #
# Colin Fox | "...graphics is my life..." | herin reflect only those #
#           +-----------------------------++ of my employer. Me. :)  #
#-----------+   Colin_Fox@MindLink.uucp    +-------------------------#
############|     Home of req.library      |##########################
######################################################################

rick@rsami.UUCP (Rick Schaeffer) (01/05/91)

>If I were to start a thread from a function in my code segment using
>CreateNewProc(), can I access variables global to the parent process?
>Or would this thread be a full-blown process for which I would need to
>set up a shared mem arrangement? The reason for this thread is to
>handle gadget input events for a window created by the parent since the
>parent is too busy to deal with them in a timely manner. I see I can
>pass the window ptr in the CreateNewProc() call. Is this kosher?

Yes, you can access globals from the thread process...provided you either
compile with LARGE data model (ie non-relative data addresses) or get the
a4 register loaded as the first thing in the thread process.  Do this with
the function "geta4()" in either Manx or Lattice or use the "__saveds" 
keyword on the function declaration in Lattice.  Note that accessing
globals makes it impossible to make your program resident, though.  It's
probably better to pass pointers to everything you need access to from 
the thread in the startup message (see below).

>
>Also, I assume I need to set up a message port in the parent process to
>send a 'kill' message.  Since this thread will be used to handle all
>window input events for this window (created by the parent), the window
>message port should be adequate for receiving the 'kill' message, no?

CreateNewProc() returns a pointer to the process structure created.  This
includes a message port that you can use to kick off the thread.  All you
have to do is allocate a message port to be used as the reply port for the
child.  An example should suffice:

struct pomsg {
	struct Message POm;
	/* you can put whatever you want after this */
	int		rc;
	char	*cmd;
	int		*ptr1;
	int		*ptr2;
	} *childmsg;

	childmsg = malloc((size_t)sizeof(struct pomsg));
	childmsg->POm.mn_ReplyPort = CreateMsgPort();
	childmsg->POm.mn_Node.ln_Type = NT_MESSAGE;
	childmsg->POm.mn_Node.ln_Pri = 0;
	/* at this point you can load up the rest of the elements of childmsg */
	ptr1 = "A message for the child"

	/* nptags contains a pointer to the function "childprocess" */
	child = CreateNewProc(nptags);
	/* now pass the child the startup message */
	PutMsg(&child->pr_MsgPort,(struct Message *) childmsg);
	.
	.
	.
	/* somewhere you want to do a waitport on childmsg->POm.mn_ReplyPort
	   this can be used to detect the completion of the thread process
	   or whatever
	*/
	WaitPort(childmsg->POm.mn_ReplyPort);
	/* clean things up */
	DeleteMsgPort(childmsg->POm.mn_ReplyPort);
	free(childmsg->cmd);
	rc = childmsg->rc;
	free(childmsg);

/* Now the thread (or child) process */
int childprocess()
{
	struct Process	*me;
	struct pomsg	*startupmsg;
	int				i;
	struct Library  *DOSBase;

	DOSBase = OpenLibrary("dos.library",0L);
	/* find our process structure */
	me = (struct Process *) FindTask(NULL);

	/* Wait for the parent to kick us off */
	WaitPort(&me->pr_MsgPort);

	/* Get the command to execute */
	startupmsg = (struct pomsg *) GetMsg(&me->pr_MsgPort);
	/* Now you can do whatever you want with the stuff in the startupmsg */
	.
	.
	.
	/* pass the exit code back to the parent */
	startupmsg->rc = whatever;
	ReplyMsg((struct Message *) startupmsg);
	CloseLibrary(DOSBase);
	return(0);
}

Note that the return address put on this message by my Amiga UUCP system
is probably bogus.  Please reply to the address in my .signature.


-- 
Rick Schaeffer          UUCP:  uunet!isc-br.isc-br.com!ricks
E. 13611 26th Ave.             ricks@isc-br.isc-br.com
Spokane, Wa.  99216     Phone: (509)928-3533