]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/apr/docs/pool-design.html
THIS BRANCH IS OBSOLETE, PLEASE READ:
[FreeBSD/FreeBSD.git] / contrib / apr / docs / pool-design.html
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     <h1>Using APR Pools</h1>
7
8     <p>
9       From <a href="http://subversion.tigris.org/">Subversion</a>, we
10       have learned a <em>lot</em> about how to use pools in a heavily
11       structured/object-based environment.
12       <a href="http://httpd.apache.org/">Apache httpd</a> is a
13       completely different beast: "allocate a request pool. use
14       it. destroy it."
15     </p>
16
17     <p>
18       In a complex app, that request-style of behavior is not
19       present. Luckily, the "proper" use of pools can be described in
20       just a few rules:
21     </p>
22
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
34       <li>
35         <p>
36           Functions should not create/destroy pools for their
37           operation; they should use a pool provided by the
38           caller. Again, the <strong>caller</strong> knows more about
39           how the function will be used, how often, how many times,
40           etc. Thus, it should be in charge of the function's memory
41           usage.
42         </p>
43         <p>
44           As an example, the caller might know that the app will exit
45           upon the function's return. Thus, the function would be
46           creating extra work if it built and destroyed a
47           pool. Instead, it should use the passed-in pool, which the
48           caller is going to be tossing as part of app-exit anyways.
49         </p>
50       </li>
51
52       <li>
53         <p>
54           Whenever an unbounded iteration occurs, a subpool should be
55           used. The general pattern is:
56         </p>
57         <blockquote>
58           <pre>
59 subpool = apr_create_subpool(pool);
60 for (i = 0; i < n; ++i) {
61   apr_pool_clear(subpool);
62
63   do_operation(..., subpool);
64 }
65 apr_pool_destroy(subpool);</pre>
66         </blockquote>
67         <p>
68           This pattern prevents the 'pool' from growing unbounded and
69           consuming all of memory. Note that it is slightly more
70           optimal to clear the pool on loop-entry. This pattern also
71           allows for a '<tt>continue</tt>' to occur within the loop,
72           yet still ensure the pool will be cleared.
73         </p>
74       </li>
75
76       <li>
77         Given all of the above, it is pretty well mandatory to pass a
78         pool to <em>every</em> function. Since objects are not
79         recording pools for themselves, and the caller is always
80         supposed to be managing memory, then each function needs a
81         pool, rather than relying on some hidden magic pool. In
82         limited cases, objects may record the pool used for their
83         construction so that they can construct sub-parts, but these
84         cases should be examined carefully. Internal pools can lead to
85         unbounded pool usage if the object is not careful.
86       </li>
87     </ul>
88
89     <hr>
90     <address>Greg Stein</address>
91     <!-- Created: Wed Jun 25 14:39:57 PDT 2003 -->
92     <!-- hhmts start -->
93 Last modified: Wed Jun 25 14:50:19 PDT 2003
94 <!-- hhmts end -->
95
96 </body></html>