pool-design.html 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
  2. <html><head>
  3. <title>Using APR Pools</title>
  4. </head>
  5. <body>
  6. <div align="right">
  7. Last modified at [$Date: 2004-11-24 16:51:51 -0600 (Wed, 24 Nov 2004) $]
  8. </div>
  9. <h1>Using APR Pools</h1>
  10. <p>
  11. From <a href="http://subversion.tigris.org/">Subversion</a>, we
  12. have learned a <em>lot</em> about how to use pools in a heavily
  13. structured/object-based environment.
  14. <a href="http://httpd.apache.org/">Apache httpd</a> is a
  15. completely different beast: "allocate a request pool. use
  16. it. destroy it."
  17. </p>
  18. <p>
  19. In a complex app, that request-style of behavior is not
  20. present. Luckily, the "proper" use of pools can be described in
  21. just a few rules:
  22. </p>
  23. <ul>
  24. <li>
  25. Objects should not have their own pools. An object is
  26. allocated into a pool defined by the constructor's caller. The
  27. <strong>caller</strong> knows the lifetime of the object and
  28. will manage it via the pool. Generally, this also means that
  29. objects will not have a "close" or a "free" since those
  30. operations will happen implicitly as part of the destruction
  31. of the pool the objects live within.
  32. </li>
  33. <li>
  34. <p>
  35. Functions should not create/destroy pools for their
  36. operation; they should use a pool provided by the
  37. caller. Again, the <strong>caller</strong> knows more about
  38. how the function will be used, how often, how many times,
  39. etc. Thus, it should be in charge of the function's memory
  40. usage.
  41. </p>
  42. <p>
  43. As an example, the caller might know that the app will exit
  44. upon the function's return. Thus, the function would be
  45. creating extra work if it built and destroyed a
  46. pool. Instead, it should use the passed-in pool, which the
  47. caller is going to be tossing as part of app-exit anyways.
  48. </p>
  49. </li>
  50. <li>
  51. <p>
  52. Whenever an unbounded iteration occurs, a subpool should be
  53. used. The general pattern is:
  54. </p>
  55. <blockquote>
  56. <pre>
  57. subpool = fspr_create_subpool(pool);
  58. for (i = 0; i < n; ++i) {
  59. fspr_pool_clear(subpool);
  60. do_operation(..., subpool);
  61. }
  62. fspr_pool_destroy(subpool);</pre>
  63. </blockquote>
  64. <p>
  65. This pattern prevents the 'pool' from growing unbounded and
  66. consuming all of memory. Note that it is slightly more
  67. optimal to clear the pool on loop-entry. This pattern also
  68. allows for a '<tt>continue</tt>' to occur within the loop,
  69. yet still ensure the pool will be cleared.
  70. </p>
  71. </li>
  72. <li>
  73. Given all of the above, it is pretty well mandatory to pass a
  74. pool to <em>every</em> function. Since objects are not
  75. recording pools for themselves, and the caller is always
  76. supposed to be managing memory, then each function needs a
  77. pool, rather than relying on some hidden magic pool. In
  78. limited cases, objects may record the pool used for their
  79. construction so that they can construct sub-parts, but these
  80. cases should be examined carefully. Internal pools can lead to
  81. unbounded pool usage if the object is not careful.
  82. </li>
  83. </ul>
  84. <hr>
  85. <address>Greg Stein</address>
  86. <!-- Created: Wed Jun 25 14:39:57 PDT 2003 -->
  87. <!-- hhmts start -->
  88. Last modified: Wed Jun 25 14:50:19 PDT 2003
  89. <!-- hhmts end -->
  90. </body></html>