Welcome, Guest. Please login or register.

Author Topic: Interprocess Communication - C/C++  (Read 2295 times)

Description:

0 Members and 1 Guest are viewing this topic.

Offline nyteschaydeTopic starter

  • VIP / Donor - Lifetime Member
  • Hero Member
  • *****
  • Join Date: Mar 2002
  • Posts: 643
    • Show only replies by nyteschayde
    • http://www.nyteshade.com
Interprocess Communication - C/C++
« on: February 07, 2017, 10:40:45 PM »
Can someone point me in the best direction to have one application talk to another on the Amiga? Because there is no memory protection, it should be possible to allocate some RAM in one process and have another access that location but there are SO MANY reasons NOT TO DO this.

So, glancing at what I can find with regards to docs, it seems like MsgPorts are the way to go? Does anyone have any working examples?

I would like to, for example, share a linked list of data between one app and another. Or, in the worst case, recreate it from data passed along. How would one go around to doing this?
Senior MTS Software Engineer with PayPal
Amigas: A1200T 060/603e PPC • A1200T 060 • A4000D 040 • A3000 (x2) • A2000 Vamp/V2 • A1200 (x4) • A1000 (x3) • A600 Vamp/V1 • A500
 

guest11527

  • Guest
Re: Interprocess Communication - C/C++
« Reply #1 on: February 08, 2017, 07:27:26 PM »
Quote from: nyteschayde;821735
Can someone point me in the best direction to have one application talk to another on the Amiga? Because there is no memory protection, it should be possible to allocate some RAM in one process and have another access that location but there are SO MANY reasons NOT TO DO this.  
It depends on what your plans is. There are many ways how processes talk to each other, but how that is done best depends on what they have to say to each other.

For example, if one program is a user application and the other is a file handler, the method of choice (message of choice) is a Dos packet and the dos.library, which provides a good interface around it.

If it is an application and exec device, the method of choice is IORequest and MsgPort, via exec.

If we are talking about two applications, the best practice is probably ARexx.

All underneath, the methods above use MsgPorts and Messages, though the way how the payload data of the messages is formatted and how the higher level protocols work are of course different.  
Quote from: nyteschayde;821735
So, glancing at what I can find with regards to docs, it seems like MsgPorts are the way to go? Does anyone have any working examples?
Well, you first create one message port per process, by
Code: [Select]
port = CreateMsgPort() To transport payload data manually between the processes, you extend a message structure
Code: [Select]
struct MyListMessage {  struct Message mlm_Message;  struct List      *mlm_List; } where the list is the list to share. (I assume you want to transport the pointer?)

Then, the easiest way how to create a message is to call
Code: [Select]
msg = (struct MyListMessage *)CreateIORequest(port,sizeof(struct MyListMessage)); It does not really matter that you do not want an IORequest here, but your own message structure. The port argument is where the message goes back to once it has been handled.

To transport then the information of the list pointer from one program to another, the sending program does a  
Code: [Select]
PutMsg(port_of_target_program,msg); and the receiving program receives it with
Code: [Select]
msg = GetMsg(port_of_target_program); This call returns NULL in case the first program has not yet send any message, or the message itself. If you want to wait until the message has been send by the first program, then do a
Code: [Select]
WaitPort(port_of_target_program); msg = GetMsg(port_of_target_program); though this then means that your 2nd program cannot do anything else while waiting.

When you are done with the message, call within the second program
Code: [Select]
ReplyMsg(msg); with which the message goes back to where it came from.

The sending program (the first program) then waits for the returned message as above, namely with
Code: [Select]
WaitPort(myport); msg = GetMsg(myport); but "myport" is this time the port of the first progam, i.e. the port of the program itself.

The message can then be recycled for something else (or just the same again, for a second roundtrip), or deleted with
Code: [Select]
DeleteIORequest((struct IORequest *)msg); and similarly, when your programs terminate, get rid of the ports with
Code: [Select]
DeleteMsgPort(port); once in the sending and once in the receiving program, each program deletes its own port.

Now a couple of pecularities: Apparently, the sending program needs to know the address of the port of the second program. As far as inter program communication is concerned, it is a "somebody else's problem", though I admit it is the very same problem you need to solve. A good solution is to make the port of the receiving (second) program public, i.e. announce it systemwise. For that, after setting up the port of the second program, use
Code: [Select]
port->mp_Node.ln_Name = "a unique fancy name"; AddPort(port); then any program that wants to talk to the second program can look for the port with
Code: [Select]
port = FindPort("a unique fancy name"); which returns the port of the target program, or NULL in case the program is not there.

Before the receiving program dies and deletes its port, the port must be made private again, of course. Thus:
Code: [Select]
RemPort(port); before running into "DeletePort()" on the receiving end.

That's all a bit chaotic, I afraid, and not a complete program, but at least the calls you need. There are a couple of pecularities I do not go into here because it rather complicates matters at this time, rather than really helping. To name a few: You probably cannot just wait for the message to come, but also need to check for user input that might reach your code, so you need to wait for multiple sources at once. Also, what happens if a port arrives at the receiving end just before you call "RemPort()", but before "DeletePort()"? The message then always remains unreplied, and the sender may just wait forever. (A typical race condition).

That's probably all for later.
 

Offline nyteschaydeTopic starter

  • VIP / Donor - Lifetime Member
  • Hero Member
  • *****
  • Join Date: Mar 2002
  • Posts: 643
    • Show only replies by nyteschayde
    • http://www.nyteshade.com
Re: Interprocess Communication - C/C++
« Reply #2 on: February 12, 2017, 05:22:42 AM »
Thomas, thank  you so much for this reply. I read it but I've been dealing with storm related damages to home and nearby roads. I live in a redwood forest in northern California and as such, with the storms of the last few weeks, we have had flooding, road washouts, trees falling (one hit our house) and so on. I haven't had as much time to code. I will be jumping and trying this stuff out shortly. Again I want to thank you for spending the time to type this up. And, as I have more intelligent questions, I will ask them.
Senior MTS Software Engineer with PayPal
Amigas: A1200T 060/603e PPC • A1200T 060 • A4000D 040 • A3000 (x2) • A2000 Vamp/V2 • A1200 (x4) • A1000 (x3) • A600 Vamp/V1 • A500