threadpool.h 3.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. // Copyright 2021 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #ifndef SANDBOX_WIN_SRC_THREADPOOL_H_
  5. #define SANDBOX_WIN_SRC_THREADPOOL_H_
  6. #include <list>
  7. #include "base/synchronization/lock.h"
  8. #include "base/win/windows_types.h"
  9. namespace sandbox {
  10. // This function signature is required as the callback when an IPC call fires.
  11. // context: a user-defined pointer that was set using ThreadProvider
  12. // reason: 0 if the callback was fired because of a timeout.
  13. // 1 if the callback was fired because of an event.
  14. typedef void(__stdcall* CrossCallIPCCallback)(void* context,
  15. unsigned char reason);
  16. // ThreadPool provides threads to run callbacks for the sandbox IPC
  17. // subsystem. See sandbox\crosscall_server.h for further details.
  18. //
  19. // ThreadPool models a thread factory. The idea is to decouple thread
  20. // creation and lifetime from the inner guts of the IPC. The contract is
  21. // simple:
  22. // - the IPC implementation calls RegisterWait with a waitable object that
  23. // becomes signaled when an IPC arrives and needs to be serviced.
  24. // - when the waitable object becomes signaled, the thread provider conjures
  25. // a thread that calls the callback (CrossCallIPCCallback) function
  26. // - the callback function tries its best not to block and return quickly
  27. // and should not assume that the next callback will use the same thread
  28. // - when the callback returns the ThreadProvider owns again the thread
  29. // and can destroy it or keep it around.
  30. //
  31. // Implementing the thread provider as a thread pool is desirable in the case
  32. // of shared memory IPC because it can generate a large number of waitable
  33. // events: as many as channels. A thread pool does not create a thread per
  34. // event, instead maintains a few idle threads but can create more if the need
  35. // arises.
  36. //
  37. // This implementation simply thunks to the nice thread pool API of win2k.
  38. class ThreadPool {
  39. public:
  40. ThreadPool();
  41. ThreadPool(const ThreadPool&) = delete;
  42. ThreadPool& operator=(const ThreadPool&) = delete;
  43. ~ThreadPool();
  44. // Registers a waitable object with the thread provider.
  45. // client: A number to associate with all the RegisterWait calls, typically
  46. // this is the address of the caller object. This parameter cannot
  47. // be zero.
  48. // waitable_object : a kernel object that can be waited on
  49. // callback: a function pointer which is the function that will be called
  50. // when the waitable object fires
  51. // context: a user-provider pointer that is passed back to the callback
  52. // when its called
  53. bool RegisterWait(const void* cookie,
  54. HANDLE waitable_object,
  55. CrossCallIPCCallback callback,
  56. void* context);
  57. // Removes all the registrations done with the same cookie parameter.
  58. // This frees internal thread pool resources.
  59. bool UnRegisterWaits(void* cookie);
  60. // Returns the total number of wait objects associated with
  61. // the thread pool.
  62. size_t OutstandingWaits();
  63. private:
  64. // Record to keep track of a wait and its associated cookie.
  65. struct PoolObject {
  66. const void* cookie;
  67. HANDLE wait;
  68. };
  69. // The list of pool wait objects.
  70. typedef std::list<PoolObject> PoolObjects;
  71. PoolObjects pool_objects_;
  72. // This lock protects the list of pool wait objects.
  73. base::Lock lock_;
  74. };
  75. } // namespace sandbox
  76. #endif // SANDBOX_WIN_SRC_THREADPOOL_H_