Simple multitasking communication

7 posts / 0 new
Last post
mritter0
mritter0's picture
Offline
Last seen: 2 years 5 months ago
Joined: 2014-04-21 21:15
Simple multitasking communication

I am trying to write a simple multitasking communication function. Not quite there.

My program starts. SetUpProcesses() to start new process. I can't talk to it. I never get past IExec->WaitPort(). (The process is started.)

I just want to PutMsg() a simple message with a int32 value to tell it what to do, 1 through 99. -1 to quit. Or even send a text message, "start", "stop", "quit". A reply back that it's done would be nice, success or fail.

I based this off Thomas Rapp's multi3.c example. Tried to update it to OS4.

Can someone straighten me out?

  1. from Protos.h:
  2. extern struct MyMessage
  3. {
  4. struct Message Msg; // need this????
  5.  
  6. int32 ActionID;
  7.  
  8. int32 ResultID;
  9. } *MyMsg;
  10.  
  11.  
  12. struct MyMessage *MyMsg;
  13. struct MsgPort *SetMenuStatePort=NULL;
  14. struct Process *SetMenuStateProcess=NULL;
  15.  
  16.  
  17. BOOL
  18. SetUpProcesses()
  19. {
  20. if (!(ReplyPort=(struct MsgPort *)IExec->AllocSysObject(ASOT_PORT,NULL)))
  21. return(FALSE);
  22.  
  23. // Probably don't need this
  24. if ((MyMsg=IExec->AllocSysObjectTags(ASOT_MESSAGE,
  25. ASOMSG_Size, sizeof(struct MyMessage),
  26. ASOMSG_ReplyPort, ReplyPort,
  27. TAG_END)))
  28. {
  29. return(FALSE);
  30. }
  31.  
  32. if (!(SetMenuStatePort=(struct MsgPort *)IExec->AllocSysObject(ASOT_PORT,NULL)))
  33. return(FALSE);
  34. else
  35. {
  36. SetMenuStateSig=PORTMASK(SetMenuStatePort);
  37.  
  38. if ((SetMenuStateProcess=IDOS->CreateNewProcTags(
  39. NP_Entry, NP_SetMenuStateProcess,
  40. // NP_NotifyOnDeathSigTask, me, /* SIGB_CHILD signal */
  41.  
  42. // NP_FinalCode, finalfunc, /* executes this ending */
  43. // NP_FinalData, fd, /* tracking data for above */
  44.  
  45. // NP_EntryCode, entryfunc, /* executes this starting */
  46. // NP_EntryData, fd, /* tracking data for above */
  47.  
  48. NP_Child, TRUE,
  49. NP_ExitData, IDOS, /* share idos with children. */
  50. TAG_DONE)))
  51. {
  52. IDOS->Printf("Started SetMenuStateProcess\n");
  53. }
  54. else
  55. return(FALSE);
  56. }
  57.  
  58. return(TRUE);
  59. }
  60.  
  61.  
  62. BOOL
  63. SendCommandToPort(struct MsgPort *replyport,struct MsgPort *cmdport,int32 ActionID)
  64. {
  65. struct MyMessage *MyMsg;
  66.  
  67. if ((MyMsg=IExec->AllocSysObjectTags(ASOT_MESSAGE,
  68. ASOMSG_Size, sizeof(struct MyMessage),
  69. ASOMSG_ReplyPort, replyport,
  70. TAG_END)))
  71. {
  72. MyMsg->Msg.mn_ReplyPort=replyport;
  73. MyMsg->ActionID=ActionID;
  74.  
  75. IExec->PutMsg(cmdport,(struct Message *)MyMsg);
  76. }
  77.  
  78. // free the message???
  79.  
  80. return(TRUE);
  81. }
  82.  
  83.  
  84. int32
  85. GetPortResponse(struct MsgPort *replyport)
  86. {
  87. struct MyMessage *MyMsg;
  88. int32 Result=-1;
  89.  
  90. if ((MyMsg=(struct MyMessage *)IExec->GetMsg(replyport)))
  91. {
  92. Result=MyMsg->ResultID;
  93. IExec->FreeSysObject(ASOT_MESSAGE,MyMsg); // how does it know the pointer???
  94. }
  95.  
  96. return(Result);
  97. }
  98.  
  99.  
  100. VOID
  101. ShutDownProcesses()
  102. {
  103. if (SetMenuStateProcess)
  104. {
  105. if (SendCommandToPort(ReplyPort,SetMenuStatePort,-1))
  106. {
  107. IExec->WaitPort(ReplyPort);
  108. GetPortResponse(ReplyPort);
  109. }
  110. }
  111.  
  112. if (SetMenuStatePort)
  113. IExec->FreeSysObject(ASOT_PORT,SetMenuStatePort);
  114.  
  115. if (MyMsg)
  116. IExec->FreeSysObject(ASOT_MESSAGE,MyMsg);
  117.  
  118. if (ReplyPort)
  119. IExec->FreeSysObject(ASOT_PORT,ReplyPort);
  120. }
  121.  
  122.  
  123. //////////////////////////////
  124.  
  125.  
  126. int32
  127. NP_SetMenuStateProcess(STRPTR *args UNUSED,int32 arglen UNUSED,struct ExecBase *sysbase)
  128. {
  129. // struct ExecIFace *iexec=(APTR)sysbase->MainInterface;
  130. // struct Process *me=(APTR)iexec->FindTask(0);
  131. // struct DOSIFace *idos=(APTR)me->pr_ExitData; /* via parent */
  132. uint32 Loc=AT_NOWHERE;
  133. int32 Action;
  134. BOOL done=FALSE;
  135. struct MyMessage *MyMsg;
  136.  
  137. // if ((MyMsg=IExec->AllocSysObjectTags(ASOT_MESSAGE,
  138. // ASOMSG_Size, sizeof(struct MyMessage),
  139. // ASOMSG_ReplyPort, replyport,
  140. // TAG_END)))
  141. {
  142. while(!done)
  143. {
  144. IExec->WaitPort(SetMenuStatePort);
  145. while((MyMsg=(struct MyMessage *)IExec->GetMsg(SetMenuStatePort)))
  146. {
  147. Action=MyMsg->ActionID;
  148. IExec->ReplyMsg(&MyMsg->Msg);
  149. switch(Action)
  150. {
  151. case 1:
  152. if (Loc != SMSLocation)
  153. {
  154. IIntuition->DisplayBeep(NULL); // just visual to know worked
  155. Loc=SMSLocation;
  156. }
  157. break;
  158.  
  159. case 2:
  160. // do something else
  161. break;
  162.  
  163. case -1:
  164. done=TRUE;
  165. break;
  166. }
  167. }
  168. }
  169.  
  170. // IExec->FreeSysObject(ASOT_MESSAGE,MyMsg);
  171. }
  172.  
  173. return(RETURN_OK);
  174. }
broadblues
broadblues's picture
Offline
Last seen: 4 years 9 months ago
Joined: 2012-05-02 21:48
Re: Simple multitasking communication

Not 100% sure by shouldn't you be allocating the SetMenuState port on it's own process? A port has a signal bit set etc and signal masks are per Process.

I not sure what your end goal is but I wondering why menu updating needs to be asynchronous? Perhaps you are doing more than that.

If you want to send textual commands you might consider using arexx.class would cut out a lot of work, though again it depends on your end goal.

[edit]
Why are you passing IDOS as NP_ExitData?

[moreedit]

You shoul do all your setup on the new process itself. Ie Allocate the Port etc.

After starting the process, the parent should wait on a signal SIGBREAKF_CTRL_F is a good or at least common choice, and the child should signal the parent when setup is done and it's safe to continue.

mritter0
mritter0's picture
Offline
Last seen: 2 years 5 months ago
Joined: 2014-04-21 21:15
Re: Simple multitasking communication

I had a hunch about where to create the ports. Will try it in the new process.

Passing IDOS in np_ExitData is from one of the AutoDocs examples.

This is my first attempt at this. Simple little thing to test and get working.

Thanks

mritter0
mritter0's picture
Offline
Last seen: 2 years 5 months ago
Joined: 2014-04-21 21:15
Re: Simple multitasking communication

Got it working. Create the port in the new process was key. Thanks

mritter0
mritter0's picture
Offline
Last seen: 2 years 5 months ago
Joined: 2014-04-21 21:15
Re: Simple multitasking communication

So I have my IDOS->CreateNewProcTags() process up and running. To truly be multitasking should ALL the processing be done in the new process? Or can it call external functions and not affect the main program? I am calling an external function and it seems to work fine. But it is simple and may not notice and "slow down" of the main program.

thomas
thomas's picture
Offline
Last seen: 3 months 1 week ago
Joined: 2011-05-16 14:23
Re: Simple multitasking communication

Tasks created by CreateNewProc are completely independent. If you call a subroutine your main routine might call, too, then this subroutine must be reentrant, i.e. it must be able to run twice at the same time. If you need serialized access to resources, you have to use SignalSemaphores. There is no automatic serialization taking place. This is especially important if you share linked lists (struct List, struct Node) or similar. These things are not protected at all, you have to protect them manually.

salass00
salass00's picture
Offline
Last seen: 6 months 2 weeks ago
Joined: 2011-02-03 11:27
Re: Simple multitasking communication


Passing IDOS in np_ExitData is from one of the AutoDocs examples.

NP_ExitData is meant for passing data to be used by the NP_ExitCode function.

Using it for anything else is not something I would recommend ever doing. If you need to pass data to a child process without using global variables either use NP_UserData or send a startup message to the process' pr_MsgPort that the process then waits for and gets before doing anything else.

Log in or register to post comments