Welcome, Guest. Please login or register.

Author Topic: Why doesn't this code starts automatically (full example with ports and message)...Also SAS linking  (Read 3971 times)

Description:

0 Members and 1 Guest are viewing this topic.

Offline Cymric

  • Hero Member
  • *****
  • Join Date: Nov 2002
  • Posts: 1031
    • Show all replies
Okay, this *has* been a long time for me, so please pay very close attention to what I say---it could be horrendously wrong. I am quite sure Piru and Karlos will find the bugs with their eyes shut, but I can't resist trying my hand at it.

First of all: your code is subject to deadlocks. Yes, I know you incorporated Delay()s to introduce 'sufficient' pause for the ports to appear. But that is a Bad Idea in general. Way better is to start the main program, have it start the second while waiting for a signal from the second program to start the message exchange. That way deadlocks are avoided.

Second, an illegal copy of the RKRF: Libraries informs me you need to set the Message's type and length prior to sending, which you have not done. You need to add the following lines below

Message_to_OtherProcess->MesstoOP.mn_ReplyPort = ReplyPort;

Message_to_OtherProcess->MesstoOP.mn_Node.ln_Type = NT_MESSAGE;
Message_to_OtherProcess->MesstoOP.mn_Length=sizeof(struct Message_to_OtherProcess));


Third, starting a program from the Workbench involves waiting for the startup message from the Workbench itself. I think the startup code already handles that, and it is also exceedingly unlikely that your code interferes with this special message as the message ports are very different. Nevertheless, I've always paid extra good care when dealing with the Workbench :-).

Finally, I have to admit I found it extremely odd that the return type of CreateProc() is struct Message *. Are you *sure* that it isn't struct Process *?

I hope this helps, and if not, well, I'm sure a Guru will be along shortly :-D.
Some people say that cats are sneaky, evil and cruel. True, and they have many other fine qualities as well.
 

Offline Cymric

  • Hero Member
  • *****
  • Join Date: Nov 2002
  • Posts: 1031
    • Show all replies
Well, waiting for a signal or message at the beginning of your main program isn't hard. Just create a named message port, have the child task find it using FindPort() and send a message to it. But that is in principle the same thing what you are trying to do here, with the exception it doesn't work ;-). (ALternatively, you can allocate a signal in the user-space range by number, say 16, and use that exclusively as a means of signalling other programs to they are ready to run. Only problem is that you have to use Wait() instead of WaitPort(), and find out the MessagePort's own signal number.)

So after inserting my code it still doesn't work. Dang. There are a few other suggestions I can help you with:
a) printf() is buffered, meaning that what you printf() is not always immediately displayed on-screen. If your program hangs before the buffer is emptied, you can wait until doomsday before you see the pent-up messages appear. So my first suggestion would be to put a fflush(stdout); after each printf() and then see where the program ends up.
b) That CreateProc()/CreateNewProc()-business is needless extra complication at this moment. Can you rewrite the programs in such a way that you have to start them both by hand and see what happens during the message exchange? If *that* is working okay, you know the error is elsewhere.

Good luck!
Some people say that cats are sneaky, evil and cruel. True, and they have many other fine qualities as well.
 

Offline Cymric

  • Hero Member
  • *****
  • Join Date: Nov 2002
  • Posts: 1031
    • Show all replies
Glad to hear that at least the messaging was doing okay now. I've dug into some forgotten Google links, hoping to find a PDF of the Guru Book, but alas, I was stuck with the criminally bad AmigaDOS manual plus some header files. Fortunately, I managed to find something which is definitely suspicious. dos/dostags.h mentions that the tags NP_CloseInput, NP_CloseOutput and NP_CloseError are all TRUE by default, meaning that the system automagically closes any open file handles for these streams upon the exit of the process. You use default input and error file handles (i.e., Open("NIL:")-sorta things), but supply the output handle of the main task. So here's what happens: the child process ends, the system closes all streams, including the output stream of the main process, thus yanking the carpet out from under the feet of your main process. It still needed that stream. So what I'm thinking is that your code actually works, but that the programs never have a chance to tell you.

To remedy this bug, either have the child process use its own output stream, or supply an additional tag to the TagList setting NP_CloseOutput to FALSE. You understand I'm kinda curious what will happen now ;-).
Some people say that cats are sneaky, evil and cruel. True, and they have many other fine qualities as well.
 

Offline Cymric

  • Hero Member
  • *****
  • Join Date: Nov 2002
  • Posts: 1031
    • Show all replies
You're not making this easy for me, are you? I'm afraid I'm at the end of my Latin, since I don't have an Amiga myself to try out your code. If this were Linux, things would be a cinch: the program dumps core, and then gdb can analyse the core quicker than a politician can change his opinion. I can only write down the following hints:

a) Try to write a program which includes the CreateNewProc()-stuff, but not the message passing. The simplest way is to comment out relevant sections with #if 0 / #endif pairs.
b) Do try the printf()/fflush() method. In addition, have the program print various values of variables, like pointers. See if they make sense.
c) Run the program through a debugger. If you use SAS/C, you can compile the program with debugging information so you don't have to stare at pure assembly. It's difficult since you're creating a separate process, and I'm fairly sure SAS/C can't debug that from within the first program.
d) Can you determine the Guru-number?

Good luck!
Some people say that cats are sneaky, evil and cruel. True, and they have many other fine qualities as well.
 

Offline Cymric

  • Hero Member
  • *****
  • Join Date: Nov 2002
  • Posts: 1031
    • Show all replies
Quote
Jose wrote:
I guess it should be obvious. Do I look stupid now? 8-)

Ah, bloody hell. Jeez. Well, yeah. After staring at it for five minutes, it struck me: you forgot a struct in the sizeof-operator. I've been in the habit of typedef'ing my structures so I don't have to write down the keyword all the time, and as an added bonus can use a simple type to indicate a pointer to the structure. So the missing keyword never bothered me, as I have not written one myself in such a situation since 1998 :-D. (C++ does this automatically for you, by the way, and I think this is a Good Thing.)

In your case it would mean that you write:

typedef struct Message_to_OtherProcess  MtoOP;
typedef struct Message_to_OtherProcess *MtoOPptr;


and then use program lines like

if (!(Message_to_OtherProcess = (MtoOPptr)AllocMem(sizeof(MtoOP), MEMF_CLEAR|MEMF_PUBLIC)))

I can recommend such abbreviations, they help you guard against mistakes like this, plus it makes programs easier to read: there is never any confusion about whether something is a true variable, or a meta-variable.
Some people say that cats are sneaky, evil and cruel. True, and they have many other fine qualities as well.