IPC: Difference between revisions
m Fix heading levels ("Skip Level 1, it is page name level." https://www.mediawiki.org/wiki/Help:Formatting) |
Add some usage info for svcReplyAndReceive |
||
Line 240: | Line 240: | ||
| Same as above except for read-only buffer. Prior(?) to the kernel version which implemented memory-permission checking for PXI buffers, this was unused and hence triggered a kernelpanic. | | Same as above except for read-only buffer. Prior(?) to the kernel version which implemented memory-permission checking for PXI buffers, this was unused and hence triggered a kernelpanic. | ||
|} | |} | ||
== SVCs == | |||
=== svcReplyAndReceive === | |||
'''Signature:''' | |||
Result ReplyAndReceive(s32* index, Handle* handles, s32 handleCount, Handle replyTarget) | |||
In a single operation, sends a IPC reply and waits for a new request. <code>handles</code> should be a pointer to an array of <code>handleCount</code> handles.<sup>TODO: Are only port/session handles supported?</sup> | |||
<code>replyTarget</code> should contain a handle to the session to send the reply to. (This us usually the session from which we received the previous request.) | |||
If <code>replyTarget</code> is 0, no reply and the call will simply wait for an incoming event.<sup>TODO: It doesn't seem like the 0xFFFF0000 command id mentioned in the above sections is necessary, but needs confirmation.</sup> | |||
Upon returning, <code>index</code> will contain an index into <code>handles</code> specifying which object changed state. | |||
If it's a server port endpoint, it means that there is a new incoming connection on that port which should be accepted using svcAcceptSession. | |||
If it's a server session endpoint it means that we received a request from that session and should process and then reply to it by calling svcReplyAndReceive again with <code>replyTarget</code> set to that session's handle. | |||
An example of a server svcReplyAndReceive loop is: | |||
#define MAX_CLIENTS 4 | |||
Handle server_port = ...; | |||
s32 requesting_index; | |||
Handle handles[1 + MAX_CLIENTS] = { server_port }; | |||
s32 connected_clients = 0; | |||
Handle reply_target = 0; | |||
while (true) { | |||
Result res = svcReplyAndReceive(&requesting_index, &handles, 1 + connected_clients, reply_target); | |||
if (res == 0xC920181A) { | |||
// Session was closed by remote | |||
// TODO: Handle disconnects | |||
reply_target = 0; | |||
continue; | |||
} | |||
if (requesting_index == 0) { | |||
// New connection in server_port | |||
ASSERT(connected_client < MAX_CLIENTS); | |||
svcAcceptSession(&handles[1 + connected_clients++], server_port); | |||
reply_target = 0; | |||
continue; | |||
} | |||
reply_target = handles[requesting_index]; | |||
// Handle command here and write reply to command buffer | |||
} |