cmUVJobServerClient.h 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. /* Distributed under the OSI-approved BSD 3-Clause License. See accompanying
  2. file Copyright.txt or https://cmake.org/licensing for details. */
  3. #pragma once
  4. #include "cmConfigure.h" // IWYU pragma: keep
  5. #include <functional>
  6. #include <memory>
  7. #include <cm/optional>
  8. #include <cm3p/uv.h>
  9. /** \class cmUVJobServerClient
  10. * \brief Job server client that can integrate with a libuv event loop.
  11. *
  12. * Use the \a Connect method to connect to an ambient job server as
  13. * described by the MAKEFLAGS environment variable, if any. Request
  14. * a token using the \a RequestToken method. The \a onToken callback
  15. * will be invoked asynchronously when the token is received. Act
  16. * on the token, and then use \a ReleaseToken to release it.
  17. *
  18. * The job server protocol states that a client process implicitly
  19. * has one free token available, corresponding to the token its
  20. * parent used to start it. \a cmUVJobServerClient will use the
  21. * implicit token whenever it is available instead of requesting
  22. * an explicit token from the job server. However, clients of
  23. * this class must still request and receive the token before
  24. * acting on it, and cannot assume that it is always held.
  25. *
  26. * If the job server connection breaks, \a onDisconnect will be
  27. * called with the libuv error. No further tokens can be received
  28. * from the job server, but progress can still be made serially
  29. * using the implicit token.
  30. */
  31. class cmUVJobServerClient
  32. {
  33. public:
  34. class Impl;
  35. private:
  36. std::unique_ptr<Impl> Impl_;
  37. cmUVJobServerClient(std::unique_ptr<Impl> impl);
  38. public:
  39. /**
  40. * Disconnect from the job server.
  41. */
  42. ~cmUVJobServerClient();
  43. cmUVJobServerClient(cmUVJobServerClient&&) noexcept;
  44. cmUVJobServerClient(cmUVJobServerClient const&) = delete;
  45. cmUVJobServerClient& operator=(cmUVJobServerClient&&) noexcept;
  46. cmUVJobServerClient& operator=(cmUVJobServerClient const&) = delete;
  47. /**
  48. * Request a token from the job server.
  49. * When the token is held, the \a onToken callback will be invoked.
  50. */
  51. void RequestToken();
  52. /**
  53. * Release a token to the job server.
  54. * This may be called only after a corresponding \a onToken callback.
  55. */
  56. void ReleaseToken();
  57. /**
  58. * Get the number of implicit and explicit tokens currently held.
  59. * This is the number of times \a onToken has been called but not
  60. * yet followed by a call to \a ReleaseToken.
  61. * This is meant for testing and debugging.
  62. */
  63. int GetHeldTokens() const;
  64. /**
  65. * Get the number of explicit tokens currently requested from the
  66. * job server but not yet received. If the implicit token becomes
  67. * available, it is used in place of a requested token, and this
  68. * is decremented without receiving an explicit token.
  69. * This is meant for testing and debugging.
  70. */
  71. int GetNeedTokens() const;
  72. /**
  73. * Connect to an ambient job server, if any.
  74. * \param loop The libuv event loop on which to schedule events.
  75. * \param onToken Function to call when a new token is held.
  76. * \param onDisconnect Function to call on disconnect, with libuv error.
  77. * \returns Connected instance, or cm::nullopt.
  78. */
  79. static cm::optional<cmUVJobServerClient> Connect(
  80. uv_loop_t& loop, std::function<void()> onToken,
  81. std::function<void(int)> onDisconnect);
  82. };