xref: /aosp_15_r20/external/virglrenderer/src/proxy/proxy_client.c (revision bbecb9d118dfdb95f99bd754f8fa9be01f189df3)
1 /*
2  * Copyright 2021 Google LLC
3  * SPDX-License-Identifier: MIT
4  */
5 
6 #include "proxy_client.h"
7 
8 #include <unistd.h>
9 
10 #include "server/render_protocol.h"
11 
12 #include "proxy_server.h"
13 
14 bool
proxy_client_destroy_context(struct proxy_client * client,uint32_t ctx_id)15 proxy_client_destroy_context(struct proxy_client *client, uint32_t ctx_id)
16 {
17    const struct render_client_op_destroy_context_request req = {
18       .header.op = RENDER_CLIENT_OP_DESTROY_CONTEXT,
19       .ctx_id = ctx_id,
20    };
21 
22    return proxy_socket_send_request(&client->socket, &req, sizeof(req));
23 }
24 
25 bool
proxy_client_create_context(struct proxy_client * client,uint32_t ctx_id,size_t ctx_name_len,const char * ctx_name,int * out_ctx_fd)26 proxy_client_create_context(struct proxy_client *client,
27                             uint32_t ctx_id,
28                             size_t ctx_name_len,
29                             const char *ctx_name,
30                             int *out_ctx_fd)
31 {
32    struct render_client_op_create_context_request req = {
33       .header.op = RENDER_CLIENT_OP_CREATE_CONTEXT,
34       .ctx_id = ctx_id,
35    };
36 
37    const size_t len = MIN2(ctx_name_len, sizeof(req.ctx_name) - 1);
38    memcpy(req.ctx_name, ctx_name, len);
39 
40    if (!proxy_socket_send_request(&client->socket, &req, sizeof(req)))
41       return false;
42 
43    struct render_client_op_create_context_reply reply;
44    int fd_count;
45    int ctx_fd;
46    if (!proxy_socket_receive_reply_with_fds(&client->socket, &reply, sizeof(reply),
47                                             &ctx_fd, 1, &fd_count))
48       return false;
49 
50    if (reply.ok != fd_count) {
51       if (fd_count)
52          close(ctx_fd);
53       return false;
54    } else if (!reply.ok) {
55       return false;
56    }
57 
58    if (!proxy_socket_is_seqpacket(ctx_fd)) {
59       close(ctx_fd);
60       return false;
61    }
62 
63    *out_ctx_fd = ctx_fd;
64    return true;
65 }
66 
67 bool
proxy_client_reset(struct proxy_client * client)68 proxy_client_reset(struct proxy_client *client)
69 {
70    const struct render_client_op_reset_request req = {
71       .header.op = RENDER_CLIENT_OP_RESET,
72    };
73    return proxy_socket_send_request(&client->socket, &req, sizeof(req));
74 }
75 
76 void
proxy_client_destroy(struct proxy_client * client)77 proxy_client_destroy(struct proxy_client *client)
78 {
79    proxy_socket_fini(&client->socket);
80    free(client);
81 }
82 
83 static bool
proxy_client_init(struct proxy_client * client,uint32_t flags)84 proxy_client_init(struct proxy_client *client, uint32_t flags)
85 {
86    const struct render_client_op_init_request req = {
87       .header.op = RENDER_CLIENT_OP_INIT,
88       .flags = flags,
89    };
90    return proxy_socket_send_request(&client->socket, &req, sizeof(req));
91 }
92 
93 struct proxy_client *
proxy_client_create(struct proxy_server * srv,uint32_t flags)94 proxy_client_create(struct proxy_server *srv, uint32_t flags)
95 {
96    struct proxy_client *client = calloc(1, sizeof(*client));
97    if (!client)
98       return NULL;
99 
100    const int client_fd = proxy_server_connect(srv);
101    if (client_fd < 0) {
102       free(client);
103       return NULL;
104    }
105 
106    proxy_socket_init(&client->socket, client_fd);
107 
108    if (!proxy_client_init(client, flags)) {
109       proxy_socket_fini(&client->socket);
110       free(client);
111       return NULL;
112    }
113 
114    return client;
115 }
116