sub-process.hon commit Merge branch 'du/cherry-is-plumbing' into maint (a6dc172)
   1#ifndef SUBPROCESS_H
   2#define SUBPROCESS_H
   3
   4#include "git-compat-util.h"
   5#include "hashmap.h"
   6#include "run-command.h"
   7
   8/*
   9 * The sub-process API makes it possible to run background sub-processes
  10 * for the entire lifetime of a Git invocation. If Git needs to communicate
  11 * with an external process multiple times, then this can reduces the process
  12 * invocation overhead. Git and the sub-process communicate through stdin and
  13 * stdout.
  14 *
  15 * The sub-processes are kept in a hashmap by command name and looked up
  16 * via the subprocess_find_entry function.  If an existing instance can not
  17 * be found then a new process should be created and started.  When the
  18 * parent git command terminates, all sub-processes are also terminated.
  19 *
  20 * This API is based on the run-command API.
  21 */
  22
  23 /* data structures */
  24
  25/* Members should not be accessed directly. */
  26struct subprocess_entry {
  27        struct hashmap_entry ent; /* must be the first member! */
  28        const char *cmd;
  29        struct child_process process;
  30};
  31
  32struct subprocess_capability {
  33        const char *name;
  34
  35        /*
  36         * subprocess_handshake will "|=" this value to supported_capabilities
  37         * if the server reports that it supports this capability.
  38         */
  39        unsigned int flag;
  40};
  41
  42/* subprocess functions */
  43
  44/* Function to test two subprocess hashmap entries for equality. */
  45extern int cmd2process_cmp(const void *unused_cmp_data,
  46                           const void *e1,
  47                           const void *e2,
  48                           const void *unused_keydata);
  49
  50/*
  51 * User-supplied function to initialize the sub-process.  This is
  52 * typically used to negotiate the interface version and capabilities.
  53 */
  54typedef int(*subprocess_start_fn)(struct subprocess_entry *entry);
  55
  56/* Start a subprocess and add it to the subprocess hashmap. */
  57int subprocess_start(struct hashmap *hashmap, struct subprocess_entry *entry, const char *cmd,
  58                subprocess_start_fn startfn);
  59
  60/* Kill a subprocess and remove it from the subprocess hashmap. */
  61void subprocess_stop(struct hashmap *hashmap, struct subprocess_entry *entry);
  62
  63/* Find a subprocess in the subprocess hashmap. */
  64struct subprocess_entry *subprocess_find_entry(struct hashmap *hashmap, const char *cmd);
  65
  66/* subprocess helper functions */
  67
  68/* Get the underlying `struct child_process` from a subprocess. */
  69static inline struct child_process *subprocess_get_child_process(
  70                struct subprocess_entry *entry)
  71{
  72        return &entry->process;
  73}
  74
  75/*
  76 * Perform the version and capability negotiation as described in the
  77 * "Handshake" section of long-running-process-protocol.txt using the
  78 * given requested versions and capabilities. The "versions" and "capabilities"
  79 * parameters are arrays terminated by a 0 or blank struct.
  80 *
  81 * This function is typically called when a subprocess is started (as part of
  82 * the "startfn" passed to subprocess_start).
  83 */
  84int subprocess_handshake(struct subprocess_entry *entry,
  85                         const char *welcome_prefix,
  86                         int *versions,
  87                         int *chosen_version,
  88                         struct subprocess_capability *capabilities,
  89                         unsigned int *supported_capabilities);
  90
  91/*
  92 * Helper function that will read packets looking for "status=<foo>"
  93 * key/value pairs and return the value from the last "status" packet
  94 */
  95
  96int subprocess_read_status(int fd, struct strbuf *status);
  97
  98#endif