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