]>
Commit | Line | Data |
---|---|---|
59c7b881 JH |
1 | #ifndef GIT_SIMPLE_IPC_H |
2 | #define GIT_SIMPLE_IPC_H | |
3 | ||
4 | /* | |
5 | * See Documentation/technical/api-simple-ipc.txt | |
6 | */ | |
7 | ||
59c7b881 JH |
8 | #ifdef SUPPORTS_SIMPLE_IPC |
9 | #include "pkt-line.h" | |
10 | ||
11 | /* | |
12 | * Simple IPC Client Side API. | |
13 | */ | |
14 | ||
15 | enum ipc_active_state { | |
16 | /* | |
17 | * The pipe/socket exists and the daemon is waiting for connections. | |
18 | */ | |
19 | IPC_STATE__LISTENING = 0, | |
20 | ||
21 | /* | |
22 | * The pipe/socket exists, but the daemon is not listening. | |
23 | * Perhaps it is very busy. | |
24 | * Perhaps the daemon died without deleting the path. | |
25 | * Perhaps it is shutting down and draining existing clients. | |
26 | * Perhaps it is dead, but other clients are lingering and | |
27 | * still holding a reference to the pathname. | |
28 | */ | |
29 | IPC_STATE__NOT_LISTENING, | |
30 | ||
31 | /* | |
32 | * The requested pathname is bogus and no amount of retries | |
33 | * will fix that. | |
34 | */ | |
35 | IPC_STATE__INVALID_PATH, | |
36 | ||
37 | /* | |
38 | * The requested pathname is not found. This usually means | |
39 | * that there is no daemon present. | |
40 | */ | |
41 | IPC_STATE__PATH_NOT_FOUND, | |
42 | ||
43 | IPC_STATE__OTHER_ERROR, | |
44 | }; | |
45 | ||
46 | struct ipc_client_connect_options { | |
47 | /* | |
48 | * Spin under timeout if the server is running but can't | |
49 | * accept our connection yet. This should always be set | |
50 | * unless you just want to poke the server and see if it | |
51 | * is alive. | |
52 | */ | |
53 | unsigned int wait_if_busy:1; | |
54 | ||
55 | /* | |
56 | * Spin under timeout if the pipe/socket is not yet present | |
57 | * on the file system. This is useful if we just started | |
58 | * the service and need to wait for it to become ready. | |
59 | */ | |
60 | unsigned int wait_if_not_found:1; | |
7cd5dbca JH |
61 | |
62 | /* | |
63 | * Disallow chdir() when creating a Unix domain socket. | |
64 | */ | |
65 | unsigned int uds_disallow_chdir:1; | |
59c7b881 JH |
66 | }; |
67 | ||
68 | #define IPC_CLIENT_CONNECT_OPTIONS_INIT { \ | |
69 | .wait_if_busy = 0, \ | |
70 | .wait_if_not_found = 0, \ | |
7cd5dbca | 71 | .uds_disallow_chdir = 0, \ |
59c7b881 JH |
72 | } |
73 | ||
74 | /* | |
75 | * Determine if a server is listening on this named pipe or socket using | |
76 | * platform-specific logic. This might just probe the filesystem or it | |
77 | * might make a trivial connection to the server using this pathname. | |
78 | */ | |
79 | enum ipc_active_state ipc_get_active_state(const char *path); | |
80 | ||
81 | struct ipc_client_connection { | |
82 | int fd; | |
83 | }; | |
84 | ||
85 | /* | |
86 | * Try to connect to the daemon on the named pipe or socket. | |
87 | * | |
88 | * Returns IPC_STATE__LISTENING and a connection handle. | |
89 | * | |
90 | * Otherwise, returns info to help decide whether to retry or to | |
91 | * spawn/respawn the server. | |
92 | */ | |
93 | enum ipc_active_state ipc_client_try_connect( | |
94 | const char *path, | |
95 | const struct ipc_client_connect_options *options, | |
96 | struct ipc_client_connection **p_connection); | |
97 | ||
98 | void ipc_client_close_connection(struct ipc_client_connection *connection); | |
99 | ||
100 | /* | |
101 | * Used by the client to synchronously send and receive a message with | |
102 | * the server on the provided client connection. | |
103 | * | |
104 | * Returns 0 when successful. | |
105 | * | |
106 | * Calls error() and returns non-zero otherwise. | |
107 | */ | |
108 | int ipc_client_send_command_to_connection( | |
109 | struct ipc_client_connection *connection, | |
110 | const char *message, struct strbuf *answer); | |
111 | ||
112 | /* | |
113 | * Used by the client to synchronously connect and send and receive a | |
114 | * message to the server listening at the given path. | |
115 | * | |
116 | * Returns 0 when successful. | |
117 | * | |
118 | * Calls error() and returns non-zero otherwise. | |
119 | */ | |
120 | int ipc_client_send_command(const char *path, | |
121 | const struct ipc_client_connect_options *options, | |
122 | const char *message, struct strbuf *answer); | |
123 | ||
124 | /* | |
125 | * Simple IPC Server Side API. | |
126 | */ | |
127 | ||
128 | struct ipc_server_reply_data; | |
129 | ||
130 | typedef int (ipc_server_reply_cb)(struct ipc_server_reply_data *, | |
131 | const char *response, | |
132 | size_t response_len); | |
133 | ||
134 | /* | |
135 | * Prototype for an application-supplied callback to process incoming | |
136 | * client IPC messages and compose a reply. The `application_cb` should | |
137 | * use the provided `reply_cb` and `reply_data` to send an IPC response | |
138 | * back to the client. The `reply_cb` callback can be called multiple | |
139 | * times for chunking purposes. A reply message is optional and may be | |
140 | * omitted if not necessary for the application. | |
141 | * | |
142 | * The return value from the application callback is ignored. | |
143 | * The value `SIMPLE_IPC_QUIT` can be used to shutdown the server. | |
144 | */ | |
145 | typedef int (ipc_server_application_cb)(void *application_data, | |
146 | const char *request, | |
147 | ipc_server_reply_cb *reply_cb, | |
148 | struct ipc_server_reply_data *reply_data); | |
149 | ||
150 | #define SIMPLE_IPC_QUIT -2 | |
151 | ||
152 | /* | |
153 | * Opaque instance data to represent an IPC server instance. | |
154 | */ | |
155 | struct ipc_server_data; | |
156 | ||
157 | /* | |
158 | * Control parameters for the IPC server instance. | |
159 | * Use this to hide platform-specific settings. | |
160 | */ | |
161 | struct ipc_server_opts | |
162 | { | |
163 | int nr_threads; | |
7cd5dbca JH |
164 | |
165 | /* | |
166 | * Disallow chdir() when creating a Unix domain socket. | |
167 | */ | |
168 | unsigned int uds_disallow_chdir:1; | |
59c7b881 JH |
169 | }; |
170 | ||
171 | /* | |
172 | * Start an IPC server instance in one or more background threads | |
173 | * and return a handle to the pool. | |
174 | * | |
175 | * Returns 0 if the asynchronous server pool was started successfully. | |
176 | * Returns -1 if not. | |
177 | * Returns -2 if we could not startup because another server is using | |
178 | * the socket or named pipe. | |
179 | * | |
180 | * When a client IPC message is received, the `application_cb` will be | |
181 | * called (possibly on a random thread) to handle the message and | |
182 | * optionally compose a reply message. | |
183 | */ | |
184 | int ipc_server_run_async(struct ipc_server_data **returned_server_data, | |
185 | const char *path, const struct ipc_server_opts *opts, | |
186 | ipc_server_application_cb *application_cb, | |
187 | void *application_data); | |
188 | ||
189 | /* | |
190 | * Gently signal the IPC server pool to shutdown. No new client | |
191 | * connections will be accepted, but existing connections will be | |
192 | * allowed to complete. | |
193 | */ | |
194 | int ipc_server_stop_async(struct ipc_server_data *server_data); | |
195 | ||
196 | /* | |
197 | * Block the calling thread until all threads in the IPC server pool | |
198 | * have completed and been joined. | |
199 | */ | |
200 | int ipc_server_await(struct ipc_server_data *server_data); | |
201 | ||
202 | /* | |
203 | * Close and free all resource handles associated with the IPC server | |
204 | * pool. | |
205 | */ | |
206 | void ipc_server_free(struct ipc_server_data *server_data); | |
207 | ||
208 | /* | |
209 | * Run an IPC server instance and block the calling thread of the | |
210 | * current process. It does not return until the IPC server has | |
211 | * either shutdown or had an unrecoverable error. | |
212 | * | |
213 | * The IPC server handles incoming IPC messages from client processes | |
214 | * and may use one or more background threads as necessary. | |
215 | * | |
216 | * Returns 0 after the server has completed successfully. | |
217 | * Returns -1 if the server cannot be started. | |
218 | * Returns -2 if we could not startup because another server is using | |
219 | * the socket or named pipe. | |
220 | * | |
221 | * When a client IPC message is received, the `application_cb` will be | |
222 | * called (possibly on a random thread) to handle the message and | |
223 | * optionally compose a reply message. | |
224 | * | |
225 | * Note that `ipc_server_run()` is a synchronous wrapper around the | |
226 | * above asynchronous routines. It effectively hides all of the | |
227 | * server state and thread details from the caller and presents a | |
228 | * simple synchronous interface. | |
229 | */ | |
230 | int ipc_server_run(const char *path, const struct ipc_server_opts *opts, | |
231 | ipc_server_application_cb *application_cb, | |
232 | void *application_data); | |
233 | ||
234 | #endif /* SUPPORTS_SIMPLE_IPC */ | |
235 | #endif /* GIT_SIMPLE_IPC_H */ |