| #ifndef GIT_SIMPLE_IPC_H |
| #define GIT_SIMPLE_IPC_H |
| |
| /* |
| * See Documentation/technical/api-simple-ipc.txt |
| */ |
| |
| #if defined(GIT_WINDOWS_NATIVE) || !defined(NO_UNIX_SOCKETS) |
| #define SUPPORTS_SIMPLE_IPC |
| #endif |
| |
| #ifdef SUPPORTS_SIMPLE_IPC |
| #include "pkt-line.h" |
| |
| /* |
| * Simple IPC Client Side API. |
| */ |
| |
| enum ipc_active_state { |
| /* |
| * The pipe/socket exists and the daemon is waiting for connections. |
| */ |
| IPC_STATE__LISTENING = 0, |
| |
| /* |
| * The pipe/socket exists, but the daemon is not listening. |
| * Perhaps it is very busy. |
| * Perhaps the daemon died without deleting the path. |
| * Perhaps it is shutting down and draining existing clients. |
| * Perhaps it is dead, but other clients are lingering and |
| * still holding a reference to the pathname. |
| */ |
| IPC_STATE__NOT_LISTENING, |
| |
| /* |
| * The requested pathname is bogus and no amount of retries |
| * will fix that. |
| */ |
| IPC_STATE__INVALID_PATH, |
| |
| /* |
| * The requested pathname is not found. This usually means |
| * that there is no daemon present. |
| */ |
| IPC_STATE__PATH_NOT_FOUND, |
| |
| IPC_STATE__OTHER_ERROR, |
| }; |
| |
| struct ipc_client_connect_options { |
| /* |
| * Spin under timeout if the server is running but can't |
| * accept our connection yet. This should always be set |
| * unless you just want to poke the server and see if it |
| * is alive. |
| */ |
| unsigned int wait_if_busy:1; |
| |
| /* |
| * Spin under timeout if the pipe/socket is not yet present |
| * on the file system. This is useful if we just started |
| * the service and need to wait for it to become ready. |
| */ |
| unsigned int wait_if_not_found:1; |
| |
| /* |
| * Disallow chdir() when creating a Unix domain socket. |
| */ |
| unsigned int uds_disallow_chdir:1; |
| }; |
| |
| #define IPC_CLIENT_CONNECT_OPTIONS_INIT { \ |
| .wait_if_busy = 0, \ |
| .wait_if_not_found = 0, \ |
| .uds_disallow_chdir = 0, \ |
| } |
| |
| /* |
| * Determine if a server is listening on this named pipe or socket using |
| * platform-specific logic. This might just probe the filesystem or it |
| * might make a trivial connection to the server using this pathname. |
| */ |
| enum ipc_active_state ipc_get_active_state(const char *path); |
| |
| struct ipc_client_connection { |
| int fd; |
| }; |
| |
| /* |
| * Try to connect to the daemon on the named pipe or socket. |
| * |
| * Returns IPC_STATE__LISTENING and a connection handle. |
| * |
| * Otherwise, returns info to help decide whether to retry or to |
| * spawn/respawn the server. |
| */ |
| enum ipc_active_state ipc_client_try_connect( |
| const char *path, |
| const struct ipc_client_connect_options *options, |
| struct ipc_client_connection **p_connection); |
| |
| void ipc_client_close_connection(struct ipc_client_connection *connection); |
| |
| /* |
| * Used by the client to synchronously send and receive a message with |
| * the server on the provided client connection. |
| * |
| * Returns 0 when successful. |
| * |
| * Calls error() and returns non-zero otherwise. |
| */ |
| int ipc_client_send_command_to_connection( |
| struct ipc_client_connection *connection, |
| const char *message, struct strbuf *answer); |
| |
| /* |
| * Used by the client to synchronously connect and send and receive a |
| * message to the server listening at the given path. |
| * |
| * Returns 0 when successful. |
| * |
| * Calls error() and returns non-zero otherwise. |
| */ |
| int ipc_client_send_command(const char *path, |
| const struct ipc_client_connect_options *options, |
| const char *message, struct strbuf *answer); |
| |
| /* |
| * Simple IPC Server Side API. |
| */ |
| |
| struct ipc_server_reply_data; |
| |
| typedef int (ipc_server_reply_cb)(struct ipc_server_reply_data *, |
| const char *response, |
| size_t response_len); |
| |
| /* |
| * Prototype for an application-supplied callback to process incoming |
| * client IPC messages and compose a reply. The `application_cb` should |
| * use the provided `reply_cb` and `reply_data` to send an IPC response |
| * back to the client. The `reply_cb` callback can be called multiple |
| * times for chunking purposes. A reply message is optional and may be |
| * omitted if not necessary for the application. |
| * |
| * The return value from the application callback is ignored. |
| * The value `SIMPLE_IPC_QUIT` can be used to shutdown the server. |
| */ |
| typedef int (ipc_server_application_cb)(void *application_data, |
| const char *request, |
| ipc_server_reply_cb *reply_cb, |
| struct ipc_server_reply_data *reply_data); |
| |
| #define SIMPLE_IPC_QUIT -2 |
| |
| /* |
| * Opaque instance data to represent an IPC server instance. |
| */ |
| struct ipc_server_data; |
| |
| /* |
| * Control parameters for the IPC server instance. |
| * Use this to hide platform-specific settings. |
| */ |
| struct ipc_server_opts |
| { |
| int nr_threads; |
| |
| /* |
| * Disallow chdir() when creating a Unix domain socket. |
| */ |
| unsigned int uds_disallow_chdir:1; |
| }; |
| |
| /* |
| * Start an IPC server instance in one or more background threads |
| * and return a handle to the pool. |
| * |
| * Returns 0 if the asynchronous server pool was started successfully. |
| * Returns -1 if not. |
| * Returns -2 if we could not startup because another server is using |
| * the socket or named pipe. |
| * |
| * When a client IPC message is received, the `application_cb` will be |
| * called (possibly on a random thread) to handle the message and |
| * optionally compose a reply message. |
| */ |
| int ipc_server_run_async(struct ipc_server_data **returned_server_data, |
| const char *path, const struct ipc_server_opts *opts, |
| ipc_server_application_cb *application_cb, |
| void *application_data); |
| |
| /* |
| * Gently signal the IPC server pool to shutdown. No new client |
| * connections will be accepted, but existing connections will be |
| * allowed to complete. |
| */ |
| int ipc_server_stop_async(struct ipc_server_data *server_data); |
| |
| /* |
| * Block the calling thread until all threads in the IPC server pool |
| * have completed and been joined. |
| */ |
| int ipc_server_await(struct ipc_server_data *server_data); |
| |
| /* |
| * Close and free all resource handles associated with the IPC server |
| * pool. |
| */ |
| void ipc_server_free(struct ipc_server_data *server_data); |
| |
| /* |
| * Run an IPC server instance and block the calling thread of the |
| * current process. It does not return until the IPC server has |
| * either shutdown or had an unrecoverable error. |
| * |
| * The IPC server handles incoming IPC messages from client processes |
| * and may use one or more background threads as necessary. |
| * |
| * Returns 0 after the server has completed successfully. |
| * Returns -1 if the server cannot be started. |
| * Returns -2 if we could not startup because another server is using |
| * the socket or named pipe. |
| * |
| * When a client IPC message is received, the `application_cb` will be |
| * called (possibly on a random thread) to handle the message and |
| * optionally compose a reply message. |
| * |
| * Note that `ipc_server_run()` is a synchronous wrapper around the |
| * above asynchronous routines. It effectively hides all of the |
| * server state and thread details from the caller and presents a |
| * simple synchronous interface. |
| */ |
| int ipc_server_run(const char *path, const struct ipc_server_opts *opts, |
| ipc_server_application_cb *application_cb, |
| void *application_data); |
| |
| #endif /* SUPPORTS_SIMPLE_IPC */ |
| #endif /* GIT_SIMPLE_IPC_H */ |