pool-design.html revision 251886
1236099Sdes<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
2236099Sdes<html><head>
3236099Sdes    <title>Using APR Pools</title>
4236099Sdes  </head>
5236099Sdes  <body>
6236099Sdes    <div align="right">
7236099Sdes      Last modified at [$Date: 2004-11-25 09:51:51 +1100 (Thu, 25 Nov 2004) $]
8236099Sdes    </div>
9255376Sdes
10236099Sdes    <h1>Using APR Pools</h1>
11236099Sdes
12236099Sdes    <p>
13236099Sdes      From <a href="http://subversion.tigris.org/">Subversion</a>, we
14236099Sdes      have learned a <em>lot</em> about how to use pools in a heavily
15236099Sdes      structured/object-based environment.
16236099Sdes      <a href="http://httpd.apache.org/">Apache httpd</a> is a
17236099Sdes      completely different beast: "allocate a request pool. use
18236099Sdes      it. destroy it."
19236099Sdes    </p>
20236099Sdes
21236099Sdes    <p>
22236099Sdes      In a complex app, that request-style of behavior is not
23236099Sdes      present. Luckily, the "proper" use of pools can be described in
24236099Sdes      just a few rules:
25236099Sdes    </p>
26236099Sdes
27236099Sdes    <ul>
28236099Sdes      <li>
29255376Sdes        Objects should not have their own pools. An object is
30236099Sdes        allocated into a pool defined by the constructor's caller. The
31236099Sdes        <strong>caller</strong> knows the lifetime of the object and
32236099Sdes        will manage it via the pool. Generally, this also means that
33236099Sdes        objects will not have a "close" or a "free" since those
34236099Sdes        operations will happen implicitly as part of the destruction
35236099Sdes        of the pool the objects live within.
36236099Sdes      </li>
37236099Sdes
38236099Sdes      <li>
39236099Sdes        <p>
40236099Sdes          Functions should not create/destroy pools for their
41236099Sdes          operation; they should use a pool provided by the
42236099Sdes          caller. Again, the <strong>caller</strong> knows more about
43236099Sdes          how the function will be used, how often, how many times,
44236099Sdes          etc. Thus, it should be in charge of the function's memory
45236099Sdes          usage.
46236099Sdes        </p>
47236099Sdes        <p>
48          As an example, the caller might know that the app will exit
49          upon the function's return. Thus, the function would be
50          creating extra work if it built and destroyed a
51          pool. Instead, it should use the passed-in pool, which the
52          caller is going to be tossing as part of app-exit anyways.
53        </p>
54      </li>
55
56      <li>
57        <p>
58          Whenever an unbounded iteration occurs, a subpool should be
59          used. The general pattern is:
60        </p>
61        <blockquote>
62          <pre>
63subpool = apr_create_subpool(pool);
64for (i = 0; i < n; ++i) {
65  apr_pool_clear(subpool);
66
67  do_operation(..., subpool);
68}
69apr_pool_destroy(subpool);</pre>
70        </blockquote>
71        <p>
72          This pattern prevents the 'pool' from growing unbounded and
73          consuming all of memory. Note that it is slightly more
74          optimal to clear the pool on loop-entry. This pattern also
75          allows for a '<tt>continue</tt>' to occur within the loop,
76          yet still ensure the pool will be cleared.
77        </p>
78      </li>
79
80      <li>
81        Given all of the above, it is pretty well mandatory to pass a
82        pool to <em>every</em> function. Since objects are not
83        recording pools for themselves, and the caller is always
84        supposed to be managing memory, then each function needs a
85        pool, rather than relying on some hidden magic pool. In
86        limited cases, objects may record the pool used for their
87        construction so that they can construct sub-parts, but these
88        cases should be examined carefully. Internal pools can lead to
89        unbounded pool usage if the object is not careful.
90      </li>
91    </ul>
92
93    <hr>
94    <address>Greg Stein</address>
95    <!-- Created: Wed Jun 25 14:39:57 PDT 2003 -->
96    <!-- hhmts start -->
97Last modified: Wed Jun 25 14:50:19 PDT 2003
98<!-- hhmts end -->
99
100</body></html>
101