| #ifndef GIT_SIMPLE_IPC_H | |
| #define GIT_SIMPLE_IPC_H | |
| /* | |
| * See Documentation/technical/api-simple-ipc.adoc | |
| */ | |
| 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, | |
| }; | |
| #ifdef SUPPORTS_SIMPLE_IPC | |
| #include "pkt-line.h" | |
| /* | |
| * Simple IPC Client Side API. | |
| */ | |
| 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 { 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, size_t message_len, | |
| 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, size_t message_len, | |
| 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, | |
| size_t request_len, | |
| 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. | |
| * | |
| * This initializes all threads but no actual work will be done until | |
| * ipc_server_start_async() is called. | |
| */ | |
| int ipc_server_init_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); | |
| /* | |
| * Let an async server start running. This needs to be called only once | |
| * after initialization. | |
| */ | |
| void ipc_server_start_async(struct ipc_server_data *server_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 */ |