summaryrefslogtreecommitdiff
path: root/Base/usr/share/man/man5/ipc.md
blob: 3df70a26ecfe053c8cce4f70905bddf0997d4d06 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
## Name

IPC - Inter-Process Communication endpoint definition format (.ipc)

## Synopsis

The IPC format of SerenityOS is a domain-specific language (DSL) used to define communication endpoints for IPC.

## Description

Informally, IPC files - with the help of the IPC compiler - are used to generate message classes that will wrap messages
for interprocess communication in the system. IPC syntax is loosely inspired by C++ headers. Generated IPC message
classes support encode and decode functions to pass messages between the processes.

Every IPC pair in the system has a client endpoint and a server endpoint that are described in the IPC files.
Each IPC endpoint should have a unique hashable name that will uniquely identify endpoints in the system.

There are 2 types of APIs that are supported by the IPC files: synchronous and asynchronous.
Synchronous function calls always wait for a response from the other side, while the asynchronous counterparts do not.
In other words, in case of the synchronous calls, the IPC library will not return until it has a response for a caller.

Ideally, all APIs for the server endpoint should be asynchronous.

## Examples

To create a new connection, you first need to generate client and server endpoints.
These endpoints should implement the communication logic using the IPC compiler-generated API messages.

Start from defining an endpoint in the IPC file in `MyServer.ipc`.

```
endpoint MyServer
{
    SyncAPI(DeprecatedString text) => (i32 status)
    AsyncAPI(i32 mode) =|
}
```

Part of the generated C++ messages:

```cpp
class SyncAPI final : public IPC::Message {
public:
    using ResponseType = SyncAPIResponse;
    SyncAPI(const DeprecatedString& text) : m_text(text) {}
    virtual ~SyncAPI() override {}
    static OwnPtr<SyncAPI> decode(...);
    virtual IPC::MessageBuffer encode(...) const override;
};
```

Then, you need to inherit your connection class from `IPC::ConnectionFromClient` with created server and client
endpoints as template parameters if it is a server connection. Otherwise, your class need to be inherited
from `IPC::ConnectionToServer` with created server and client endpoints as template parameters and from the client
endpoint class.

Part of the connection implementations:

```cpp
// Server side.
namespace MyServer {

class ConnectionFromClient final
    : public IPC::ConnectionFromClient<MyClientEndpoint, MyServerEndpoint> {};

}

// Client side.
namespace MyClient {
    
    class Client final
        : public IPC::ConnectionToServer<MyClientEndpoint, MyServerEndpoint>
        , public MyClientEndpoint {};
    
}
```

Note, there are two types of functions for sending the messages: synchronous and asynchronous. The generated
asynchronous functions are prefixed with `async_` and the names of the synchronous functions are not changed.

## See also

- [`Meta/Lagom/Tools/CodeGenerators/IPCCompiler/main.cpp`](../../../../../Meta/Lagom/Tools/CodeGenerators/IPCCompiler/main.cpp)
- [ipc(4)](help://man/4/ipc) (IPC Unix socket documentation)